前三篇文章,我们几乎把索引底层的物理结构和失效陷阱给扒了个底朝天。
理论上,只要你遵守了“最左前缀法则”,避开了“函数刺客”和“隐式转换”,你的查询就应该快如闪电。
但真实的生产环境往往充满着魔幻色彩:有时候你明明建了极其完美的联合索引,SQL 写得也无比规范,但线上系统一跑,依然慢得像拖拉机!你气急败坏地跑去查,发现 MySQL 竟然傲娇地把你的索引扔在一边,又去跑全表扫描了!
“凭什么不走我的索引?!”
这就好比你生病了去医院,不能只靠猜。高级的数据库“老中医”从来不盲猜,他们会直接给 MySQL 拍一张“B 超单”——EXPLAIN命令。
今天,我们就把 MySQL 的大脑(优化器)剖开来看,带你读懂这张 B 超单上的每一个致命指标。
一、 优化器的算盘:为什么它宁可全表扫描,也不用你的索引?
在讲EXPLAIN之前,必须先破除一个迷信:建了索引,MySQL 就必须得用。
前面我们讲过,MySQL 的 Server 层有一个极其聪明的“项目经理”——优化器(Optimizer)。优化器是个不折不扣的现实主义者,它脑子里只有一个指标:成本(Cost)。
假设表里有 100 万条数据,你写了SELECT * FROM users WHERE age > 20;(假设有 80 万人都大于 20 岁,age上有索引)。
项目经理在脑子里快速算了笔账:
方案 A(走索引):先去
age索引树上查到 80 万个主键 ID(顺序 I/O,快),然后再拿着这 80 万个 ID 回到主键树里做80 万次回表查询。回表是极其昂贵的