确认慢查询日志生效需同时满足:slow_query_log=on、slow_query_log_file路径可写、long_query_time设置合理(如1.0秒),并执行set global slow_query_log=on(mysql 5.7+默认关闭,且需写入my.cnf持久化)。

怎么确认慢查询日志真的在记录?
很多情况下你以为开启了,其实没生效。关键看三个配置是否同时满足:slow_query_log 必须为 ON,slow_query_log_file 指向可写路径,且 long_query_time 设得合理(默认 10 秒,线上建议调成 1.0 或 0.5)。用 SHOW VARIABLES LIKE 'slow%'; 和 SHOW VARIABLES LIKE 'long_query_time'; 立刻验证。特别注意:MySQL 5.7+ 默认关闭慢日志,即使你改过配置,也要执行 SET GLOBAL slow_query_log = ON; 才真正启用——重启前的这个 SET 不会持久化,必须写进 my.cnf 的 [mysqld] 段。
日志里哪些字段对定位最有用?
别被大段日志吓住,盯住三行就够了:# Time: 看发生时间,结合业务高峰交叉比对;# Query_time: 实际执行耗时,注意单位是秒(带微秒);SET timestamp=... 下面那条 SELECT/UPDATE/INSERT... 才是真凶。常见干扰项:Rows_examined 高但 Query_time 低,说明走了索引但结果集大;Rows_sent 小但 Rows_examined 极大,大概率缺索引或索引失效。如果看到 Using temporary; Using filesort 出现在 EXPLAIN 结果里,基本就是排序/分组没走索引。
EXPLAIN 看什么才能快速判断瓶颈?
对慢日志里的 SQL 直接跑 EXPLAIN FORMAT=TRADITIONAL,重点关注:
-
type字段:出现ALL(全表扫描)或index(全索引扫描)必须优化 -
key字段:为NULL表示没走索引,哪怕有索引也可能是类型不匹配(比如字符串字段用数字查询) -
rows字段:预估扫描行数,若远大于实际返回行数(Rows_sent),说明筛选条件没有效利用索引 -
Extra字段:Using where正常,Using index condition是好信号,但Using temporary或Using filesort就得重构查询或加覆盖索引
加索引不是万能解,哪些情况加了也没用?
索引加错位置或类型,等于白干:
- WHERE 条件里对字段用了函数,比如
WHERE YEAR(create_time) = 2024,哪怕create_time有索引也失效 - 联合索引顺序和查询条件不匹配,比如索引是
(a,b,c),但查询只用了b = ?和c = ?,跳过了最左列a,索引直接被忽略 - 区分度极低的字段单独建索引,比如
status TINYINT只有 0/1,优化器大概率选择全表扫描 - 数据量小(比如几千行)的表,加索引反而增加 B+ 树维护开销,优化器可能主动放弃
WHERE、ORDER BY、GROUP BY 的字段组合来设计,优先覆盖高频慢查。慢查询日志本身不产生优化,它只负责暴露问题。真正卡点往往藏在索引设计与查询写法的耦合细节里——比如隐式类型转换让索引失效,或者 OR 条件破坏了索引合并策略。这些地方不跑 EXPLAIN 对比,光看日志根本发现不了。











