如何查看Laravel API执行的数据库语句并排查N+1问题?Debugbar API路由失效
我明白你现在的痛点——Debugbar在web路由里用得好好的,但API路由里就是看不到查询日志,没法排查N+1问题。下面给你几个实用的方案,亲测有效:
方法一:让barryvdh/laravel-debugbar支持API路由
默认情况下,Debugbar的中间件只注册在web中间件组里,API路由用的是api组,所以没生效。你可以这样调整:
全局启用API路由的Debugbar
打开app/Http/Kernel.php,找到$middlewareGroups里的api数组,把Debugbar的中间件加进去:'api' => [ \Barryvdh\Debugbar\Middleware\DebugbarMiddleware::class, // 其他原有中间件... 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ],注意:这样所有API请求都会触发Debugbar,建议只在本地开发环境这么做,别上生产。
局部启用(更推荐)
如果不想全局开,只给特定API路由加Debugbar:// 在routes/api.php里 Route::get('/your-endpoint', [YourController::class, 'method']) ->middleware('debugbar');或者在控制器方法里手动开启:
public function yourMethod() { app('debugbar')->enable(); // 你的业务逻辑... }另外还要确保
.env里APP_DEBUG=true,并且config/debugbar.php里enabled设置为true(默认是env('APP_DEBUG', false),所以只要APP_DEBUG开了就没问题)。
之后你可以在浏览器开发者工具的「Network」标签里,找到对应的API请求,查看响应头里的X-Debugbar-Link,或者直接看Debugbar的「AJAX」面板,就能看到查询日志了。
方法二:用Laravel自带的查询日志(无需额外工具)
如果不想折腾Debugbar,Laravel本身就有查询日志功能,非常直接:
在路由/控制器里开启日志
在你的API业务代码前加上开启日志的代码,执行完业务后获取日志:use Illuminate\Support\Facades\DB; public function yourApiMethod() { // 开启查询日志 DB::enableQueryLog(); // 你的业务逻辑,比如查询模型、返回数据 $users = User::all(); // 这里如果有N+1,会触发多次查询 // 获取查询日志 $queries = DB::getQueryLog(); // 可以把日志附加到响应里,方便查看 return response()->json([ 'data' => $users, 'query_log' => $queries ]); // 或者写到日志文件里,不污染响应 // \Illuminate\Support\Facades\Log::info('API Query Log', $queries); }查询日志里会包含每个查询的SQL语句、绑定参数、执行时间,你能清楚看到有没有重复的查询(比如多次查询同一张表的不同行,就是典型的N+1)。
用中间件全局记录API查询
如果想给所有API请求都记录查询,可以写个自定义中间件:// 创建中间件:php artisan make:middleware LogApiQueries public function handle(Request $request, Closure $next) { DB::enableQueryLog(); $response = $next($request); if (app()->environment('local')) { // 只在本地记录 Log::info('API Request Queries', [ 'url' => $request->fullUrl(), 'queries' => DB::getQueryLog() ]); } return $response; }然后把这个中间件加到
api中间件组里,这样所有API请求的查询都会写到storage/logs/laravel.log里。
方法三:用Laravel Telescope(官方调试神器)
如果需要更全面的调试功能,包括N+1自动提示,Laravel Telescope绝对是首选:
- 安装Telescope
composer require laravel/telescope --dev php artisan telescope:install php artisan migrate - 访问Telescope
在本地环境访问http://your-app.test/telescope,点击左侧的「Requests」,找到你的API请求,就能看到所有执行的数据库查询,而且Telescope会自动标记出N+1查询(红色警告),非常直观。
注意:Telescope默认只在本地环境启用,生产环境需要配置权限才能访问。
排查N+1问题的小技巧
不管用哪种方法,当你看到查询日志里有大量重复的、类似SELECT * FROM postsWHEREuser_id = ?的查询时,基本就是N+1问题了。解决方法很简单:在模型查询时用with()预加载关联,比如把User::all()改成User::with('posts')->get(),这样就会变成一次主查询+一次关联查询,避免N+1。
内容的提问来源于stack exchange,提问作者Wouter

