Laravel 如何查看实际执行的 SQL 查询
DB::enableQueryLog() + DB::getQueryLog() 查看查询日志;DB::listen() 实时监听每条 SQL 及耗时;dd($query->toSql()) 看单条构造器 SQL。附 Telescope 与 APM 方案。
一句话回答:三种方式按需选:调试用 DB::enableQueryLog() 开启查询日志,跑完操作后 dd(DB::getQueryLog()) 打印该连接启用日志后记录的查询;实时监控用 DB::listen(fn($q) => Log::debug($q->sql));只想看某条正在构造的查询用 $query->toSql()(不执行)。
版本范围:以下 Laravel 示例按 12.x 官方文档核对;其他版本请检查对应 API 与配置差异。
方法一:查询日志(调试首选)
DB::enableQueryLog(); // 默认关闭,需显式开启
$users = User::where('active', 1)->get(); // 你的业务代码
dd(DB::getQueryLog());
// 输出数组:每条含 query(带占位符 SQL)、bindings(绑定值)、time(毫秒)
注意:getQueryLog() 里的 query 是带 ? 占位符的,真实参数在 bindings 里。数据库通常分别接收预处理语句与绑定值,并非一定有一条拼好的 SQL 字符串;调试展开仅作可读表示,不应拿去重新执行。
方法二:DB::listen 实时监听
在 AppServiceProvider::boot() 或临时代码里:
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
if (app()->environment('local')) {
DB::listen(function ($query) {
Log::debug($query->sql, [
'time_ms' => $query->time,
// 不默认记录 bindings,避免密码、Token 与个人数据入日志
]);
});
}
Laravel 发出 QueryExecuted 事件时触发,可用于观察通过 Laravel 数据库层执行的查询;直接绕过该层的驱动调用不会因此自动可见。重复查询是 N+1 的线索,仍需结合调用位置判断。
方法三:单条查询看 SQL
$query = User::where('active', 1)->orderBy('created_at');
dump($query->toSql()); // select * from `users` where `active` = ? ...
dump($query->getBindings()); // [1]
// 支持此方法的 Laravel 版本可展开参数,仅限本地脱敏调试
User::where('active', 1)->dumpRawSql();
toSql() 不执行查询,只返回构造好的 SQL 字符串。
方法四:Laravel Telescope / Debugbar
- Laravel Telescope(官方):按官方流程安装包、发布资源、运行所需迁移并配置 watcher/filter 后,Queries 面板可查看被记录的查询及耗时。还需配置访问授权、保留/清理策略和敏感参数处理,不能直接向公网开放
- laravel-debugbar(第三方):页面底部调试条实时显示本请求 SQL,开发环境神器
生产环境别开 Telescope 全量记录(有性能开销),用采样或换 APM。
常见问题(FAQ)
Q:getQueryLog() 返回空数组?
A:两个原因:enableQueryLog() 在执行查询之后才被调用(顺序反了);或者查询走的是另一个数据库连接——query log 是按连接分开的,对对应连接 DB::connection('xxx')->enableQueryLog()。
Q:生产环境能开着 query log 吗?
A:不建议。查询日志把每条 SQL 存在内存里,长进程(Octane/队列 worker)会持续累积撑爆内存。生产排查慢查询用 MySQL slow log 或 APM。
Q:绑定的参数和 SQL 怎么拼成完整可执行的语句?
A:支持该 API 的版本可在 DB::listen 的 QueryExecuted 事件或 Builder 上用 toRawSql();getQueryLog() 返回的是数组,数组条目没有这个方法。不要用 vsprintf 或简单替换问号自行拼接,容易破坏引用/转义,也可能泄露敏感参数。
核查依据
本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。