mysql如何选择最优执行计划_SQL优化原理解析

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

MySQL 选择最优执行计划,不是靠“猜”,而是基于成本模型(Cost-Based Optimizer, CBO)对多个候选路径做量化评估后选成本最低的那个——

cost
越低,越可能被选中。

看懂 EXPLAIN 是判断“是否最优”的唯一入口

不查

EXPLAIN
,就等于闭眼调优。它暴露了优化器的全部决策依据:

type
字段直接反映访问效率:从
const
eq_ref
ref
range
index
ALL
,性能逐级下降;出现
ALL
基本意味着没走索引或索引失效
key
possible_keys
不一致?说明优化器放弃了你建的索引——常见原因包括:索引列参与了函数/表达式、隐式类型转换、
WHERE
条件未覆盖最左前缀
rows
是预估扫描行数,不是实际值;但若远大于结果集(比如查 1 行却扫 10 万行),大概率存在索引未命中或统计信息过期
Extra
中的
Using filesort
Using temporary
是强信号:ORDER BY / GROUP BY 没走索引,正在用磁盘临时文件排序或建临时表

为什么明明有索引,优化器却不选?

索引存在 ≠ 索引可用。优化器弃用索引的核心原因是:它算出来用这个索引的成本反而更高。

数据分布倾斜:比如某字段 95% 值为
'active'
,即使加了索引,优化器也会认为全表扫描更便宜(因为要回表读取大量数据)
统计信息陈旧:
ANALYZE TABLE
没跑过,优化器基于错误基数估算成本;尤其在大批量 INSERT/DELETE 后必须手动刷新
联合索引顺序错位:
KEY idx_name_age (name, age)
支持
WHERE name = ?
WHERE name = ? AND age > ?
,但不支持
WHERE age = ?
隐式转换强制放弃索引:
WHERE phone = 13800138000
(phone 是
VARCHAR
)会触发字符串→数字转换,导致索引失效

EXPLAIN ANALYZE 才是真·照妖镜

EXPLAIN
只显示预估,而
EXPLAIN ANALYZE
(MySQL 8.0+)会真实执行并返回各阶段耗时、实际扫描行数、是否真正用了索引等硬指标。

EXPLAIN ANALYZE SELECT * FROM employees WHERE name = '张三' AND age > 25;
对比
rows
(预估)和
actual rows
(实际):若相差 10 倍以上,说明统计不准或查询条件选择性误判
观察
actual time
分布:如果 “Index lookup” 很快但 “Read data” 占比极高,说明回表开销大,考虑改成覆盖索引
注意 “Materialize” 或 “Create temporary table” 出现场景:这类操作无法通过加索引消除,需重构 SQL 或调整
tmp_table_size
等参数

真正卡住性能的,往往不是“有没有索引”,而是“优化器信不信这个索引值得用”。别只盯着

CREATE INDEX
,多跑
EXPLAIN ANALYZE
,再结合
SHOW INDEX
INFORMATION_SCHEMA.STATISTICS
看基数,才能看清成本模型背后的真实逻辑。

相关推荐