定位 laravel 页面加载慢应先分析数据库查询:用 db::enablequerylog() 抓取详情;debugbar 实时查看总耗时与 n+1;db::listen() 监控慢查询;telescope 回溯全链路耗时及堆栈。

页面加载慢,第一反应不该是加缓存或换服务器,而是先看清“谁在拖后腿”——尤其是数据库查了多少次、花了多少时间。Laravel 提供了轻量又直接的方式,不用装插件也能快速定位问题。
用 DB::enableQueryLog() 快速抓取查询详情
这是最基础也最有效的手段,适合单点排查:
- 在控制器方法开头加 DB::enableQueryLog()
- 执行完业务逻辑(比如
User::with('posts')->get())后,立即调用dd(DB::getQueryLog()) - 结果里每条记录含 query(SQL语句)、bindings(参数值)、time(毫秒),一眼就能看出哪条查得久、哪条重复出现
- 注意:这个功能只对当前请求有效,且生产环境默认关闭,别写在中间件里全局启用
用 Laravel Debugbar 实时看总耗时和查询次数
比手动 dd 更直观,适合日常开发调试:
- 安装:
composer require barryvdh/laravel-debugbar --dev - 发布配置:
php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider" - 确保 .env 中有
APP_DEBUG=true和DEBUGBAR_ENABLED=true - 刷新页面,底部会出现调试栏,点 Database 标签页,能看到:
– Query Count(本次请求总共执行了几条 SQL)
– 总耗时(Total Time)
– 每条 SQL 的执行时间、是否重复(Duplicates > 1 就是典型 N+1)
用 DB::listen() 长期监控慢查询
适合想持续观察、不靠手动触发的场景:
- 在 AppServiceProvider::boot() 里注册监听:
DB::listen(function ($event) { if ($event->time > 200) { \Log::warning('Slow query', [ 'sql' => $event->sql, 'bindings' => $event->bindings, 'time' => $event->time ]); } });- 这样所有超过 200ms 的查询都会记进日志,还能配合 grep 统计高频 SQL(比如循环查头像这种“单次不慢、累计致命”的情况)
用 Laravel Telescope 查全链路耗时
当问题不固定、需要回溯历史请求时,Telescope 是更可靠的工具:
- 安装:
composer require laravel/telescope,然后运行php artisan telescope:install和php artisan migrate - 开启后访问 /telescope,进 Queries 标签页,可按 Duration 排序,直接看到耗时最高的那几条
- 点击单条记录,能查看完整堆栈(Stack Trace),精准定位到是哪个控制器、哪行代码触发的
- 它还会记录内存占用、响应状态、中间件执行顺序,帮你判断是不是数据库之外的因素(比如序列化大对象)也在拖慢页面











