mysql慢日志启用且explain显示rows与rows_examined显著下降才是优化有效的标志,需先确认slow_query_log=on、long_query_time合理、log_queries_not_using_indexes=on,并通过sql注释或db::getlastsql()关联thinkphp接口。

ThinkPHP 项目里 SQL 慢,90% 不是框架问题,而是 MySQL 没开慢日志、没看 EXPLAIN、索引没加对 —— 先让数据库“开口说话”,再动手改代码。
如何确认 ThinkPHP 是否触发了慢查询日志
ThinkPHP 本身不生成慢查询日志,它只是执行 SQL;真正记录耗时的是 MySQL。所以第一步不是改 PHP,而是确认 MySQL 的慢日志是否真的在工作:
- 登录 MySQL 执行
SHOW VARIABLES LIKE 'slow_query_log';,返回ON才算启用 - 检查阈值:
SHOW VARIABLES LIKE 'long_query_time';,生产环境建议设为1.0,调试期可临时设为0.5 - 务必开启
log_queries_not_using_indexes = ON(写进my.cnf的[mysqld]段),否则连“没走索引但很快”的语句都看不到 - ThinkPHP 日志(
runtime/log/)里只有“SQL 执行了”,没有耗时和扫描行数,不能替代 MySQL 慢日志
怎么把慢 SQL 和 ThinkPHP 的具体接口对上号
光知道 SELECT * FROM user WHERE mobile=? 慢没用,得定位到是哪个控制器、哪个方法、什么参数下触发的。靠猜效率太低:
- 在 ThinkPHP 查询前手动加注释,比如
$this->where('mobile', $phone)->comment('api_user_profile')->select();,MySQL 日志里就会出现/* api_user_profile */ SELECT ... - 用
Db::getLastSql()+microtime(true)在关键接口里包一层耗时统计,把 SQL 和毫秒级耗时一起打到 ThinkPHP 日志中(仅限调试环境) - 避免依赖
trace或debug模式输出的 SQL —— 它们不包含Rows_examined这类关键指标,无法判断是否全表扫描
用 EXPLAIN 看懂 ThinkPHP 生成的 SQL 到底卡在哪
ThinkPHP 的 where、order、limit 都会转成标准 SQL,但复合条件+分页很容易写出隐式全表扫描。直接拿日志里的 SQL 去 EXPLAIN:
- 重点看
type字段:ALL或index是危险信号;ref、range、const才算合理 - 对比
rows和Rows_examined(慢日志里有):如果rows=100但Rows_examined=50000,说明索引没覆盖查询条件或排序字段 - ThinkPHP 的
with关联查容易触发 N+1,EXPLAIN看不到嵌套,得结合日志里实际执行的多条 SQL 数量来判断 - 不要只看单条
EXPLAIN结果 —— 复合索引要遵循最左前缀,比如INDEX(status, created_at)能加速WHERE status=1 ORDER BY created_at DESC,但对WHERE created_at > '2025-01-01'无效
给 ThinkPHP 表加索引时最容易踩的三个坑
加索引不是越多越好,ThinkPHP 的链式调用会让字段组合变得隐蔽:
- 忽略时间范围查询的索引顺序:比如常用
WHERE category_id = ? AND publish_time > ? ORDER BY sort ASC,应建INDEX(category_id, publish_time, sort),而不是分开建三个单列索引 - 在
LIKE '%关键词'字段上建普通 B-Tree 索引无效,得考虑全文索引或前置模糊改后置(LIKE '关键词%') - ThinkPHP 的
paginate()默认用SELECT COUNT(*)统计总数,如果WHERE条件没走索引,这个 COUNT 就会扫全表 —— 先确保 COUNT 对应的 WHERE 有高效索引,再考虑用simplePaginate跳过总数统计
真正卡住 ThinkPHP 查询性能的,往往不是 ORM 写法本身,而是 MySQL 执行计划里那几行被忽略的 rows 和 key。日志开了、EXPLAIN 跑了、索引加了,但没核对 Rows_examined 是否大幅下降,优化就等于没做。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











