mysql执行SQL过程中如何查看执行计划_mysql执行监控

来源:这里教程网 时间:2026-02-28 20:50:38 作者:

用 EXPLAIN 看执行计划最直接

MySQL 里查 SQL 执行计划,

EXPLAIN
是首选,它不真正执行语句,只分析优化器打算怎么走。对慢查询或怀疑索引没生效的语句,加
EXPLAIN
前缀就能看到关键信息:

type
字段反映连接类型,
ALL
表示全表扫描,
ref
range
通常更健康
key
显示实际使用的索引名,为空说明没走索引(注意:
possible_keys
只是候选,不等于真用了)
rows
是优化器预估扫描行数,和实际差距大时,往往说明统计信息过期,可运行
ANALYZE TABLE
更新
ORDER BY
GROUP BY
的语句,若
Extra
出现
Using filesort
Using temporary
,大概率需要覆盖索引优化

想看真实执行过程得开 performance_schema

EXPLAIN
是预测,要监控真实执行中的资源消耗、等待事件、IO 次数,必须依赖
performance_schema
。默认开启但部分消费者可能被关掉,先确认:

SELECT * FROM performance_schema.setup_consumers WHERE NAME LIKE 'events_statements%';

确保

events_statements_current
events_statements_history_long
对应的消费者为
ENABLED
。之后查最近执行的语句:

SELECT DIGEST_TEXT, TIMER_WAIT, LOCK_TIME, ROWS_SENT, ROWS_EXAMINED 
FROM performance_schema.events_statements_history_long 
WHERE DIGEST_TEXT LIKE '%UPDATE orders%' 
ORDER BY TIMER_WAIT DESC LIMIT 5;
TIMER_WAIT
单位是皮秒(10⁻¹² 秒),除以 10⁹ 得秒级耗时
ROWS_EXAMINED
EXPLAIN
rows
不同,这是真实读取的行数,对比二者能判断优化器估算是否靠谱
如果
LOCK_TIME
显著高于
TIMER_WAIT
,说明锁争用严重,不是 SQL 本身慢,而是被堵住了

SHOW PROCESSLIST 只能看“卡在哪”,不能看“为什么卡”

SHOW PROCESSLIST
SELECT * FROM information_schema.PROCESSLIST
能立刻看到当前连接状态,但它只告诉你线程卡在
Waiting for table metadata lock
Sending data
这类模糊阶段,无法定位到具体瓶颈。

状态为
Updating
Time
持续增长?不一定在写数据,可能是二级索引回表慢,或是 MVCC 版本链遍历长
状态为
Locked
?优先查
performance_schema.data_locks
data_lock_waits
,确认谁持有了什么锁
别依赖
Id
排序判断“谁最老”,
Time
字段才是该连接持续处于当前状态的秒数

慢日志(slow_query_log)是回溯问题的关键证据

线上出问题后复盘,

slow_query_log
是唯一能还原“当时那条 SQL 到底干了什么”的来源。务必打开并合理配置:

long_query_time = 1
(秒),别用默认的 10 秒——很多业务扛不住 10 秒延迟
log_queries_not_using_indexes = ON
,但注意:这会记录所有未走索引的查询,包括
SELECT COUNT(*) FROM tiny_table
这种无害语句,需配合过滤使用
日志里每条记录末尾的
# Query_time: ...  Rows_examined: ...
比 SQL 文本本身更有诊断价值
mysqldumpslow
pt-query-digest
解析,别手动翻文本;尤其注意
Rows_examined/Rows_sent
比值,远大于 1 就意味着大量无效扫描

真正难的不是查执行计划,而是把

EXPLAIN
的预测、
performance_schema
的实时指标、慢日志里的历史现场三者对齐——比如某条语句在慢日志里
Rows_examined=50000
,但
EXPLAIN
显示
rows=100
,那第一反应不是改 SQL,而是检查统计信息或是否存在隐式类型转换。

相关推荐