thinkphp无一键开启慢查询日志功能:tp5.x需配置log_sql、trigger_sql和slow_query_time(单位毫秒)并配合trigger_sql=true生效;tp6废弃该参数,改用db::listen()监听并手动判断耗时阈值,同时需协同mysql慢日志与php-fpm slowlog三者分析。

ThinkPHP 本身没有“一键开启慢查询日志”的配置项,database.php 里的 slow_query_time 参数仅在 TP5.x 中有效,且必须配合 trigger_sql => true 才会触发记录;TP6 已移除此参数,改用事件监听机制实现。真正能定位到“哪条 SQL 慢、为什么慢、谁调用的”,靠的是框架层 + 数据库层 + PHP 运行层三者协同,缺一不可。
database.php 中正确启用框架层慢 SQL 捕获(TP5.1)
在 app/database.php 或 config/database.php 中,确保以下配置生效:
-
'log_sql' => true:开启 SQL 日志基础能力 -
'trigger_sql' => true:允许框架在查询完成后触发日志逻辑(关键!不设此项,slow_query_time 不起作用) -
'slow_query_time' => 500:单位毫秒,表示执行超 500ms 的 SQL 将被标记为慢查询 -
'sql_explain' => false:禁用自动 EXPLAIN,避免额外开销干扰真实耗时
注意:该方式记录的只是“SQL 文本 + 耗时”,不含 URL、用户 ID、请求参数等上下文,需手动在监听逻辑中补充。
TP6 推荐做法:用 Db::listen() 注册耗时监听
TP6 废弃了 slow_query_time,转而提供更灵活的事件钩子。推荐在 app/common.php 或全局中间件中添加:
- 调用
Db::listen(function ($sql, $time, $explain) { ... }) - 在回调内计算真实耗时:
$duration = $time * 1000(单位毫秒) - 与阈值比对,超时则用
Log::channel('slowsql')->info(...)写入独立日志通道 - 可顺手注入
request()->url()、session_id()或input()等上下文信息
这样既能精准捕获慢 SQL,又能关联业务入口,排查效率远高于纯 MySQL 慢日志。
别只盯 database.php:MySQL 层和 PHP-FPM 层必须同步看
单靠框架日志容易误判。比如 SQL 只跑 10ms,但接口整体响应 3s,问题可能出在 curl、文件读写或扩展阻塞上:
-
MySQL 层:确认
slow_query_log = ON,long_query_time = 1.0,并开启log_queries_not_using_indexes = ON -
PHP-FPM 层:在对应 PHP 版本的
php-fpm.conf中启用:slowlog = /www/wwwlogs/php_slow.log和request_slowlog_timeout = 2s - 三类日志内容互不重叠:框架日志告诉你“哪条 SQL 慢”,MySQL 日志告诉你“它扫描了多少行”,PHP-FPM slowlog 告诉你“整个脚本卡在哪一行”
日志写入要注意落盘和隔离
慢查询日志若混在主日志里,排查时等于大海捞针:
- 为慢 SQL 单独配置一个日志通道,例如
'channels' => ['slowsql' => [...]],路径设为runtime/log/slow/ - Swoole 或常驻进程模式下,
runtime/log/日志可能缓存不刷盘,建议在监听回调末尾加ob_flush(); flush(); - 避免直接
file_put_contents()写文件,统一走Log::write(),便于后续对接 ELK 或告警系统
不复杂但容易忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











