为何添加索引后EXPLAIN语句结果无变化?附建表脚本
为啥加了索引EXPLAIN结果没变化?
嘿,这个问题我日常排查SQL性能时经常碰到,结合你给出的建表脚本,咱们来捋捋几种最常见的原因:
1. 索引根本没生效(或者建错了)
首先得确认你建的索引真的和你的查询匹配,而且确实创建成功了:
- 先跑
SHOW INDEX FROM 你的表名;(比如SHOW INDEX FROM sailors;),看看你加的索引是不是在列表里,字段、类型都对不对。 - 比如你给
sailors.age建了索引,但你的查询是WHERE rating > 3,那这个索引完全派不上用场,EXPLAIN自然不会变。
2. 表数据量太小,优化器选了全表扫描
如果你的表刚建完,只插了几条测试数据,MySQL的优化器会算一笔账:走索引还要额外回表取数据,反而不如直接全表扫来得快。这种情况下哪怕你建了正确的索引,EXPLAIN里还是会显示type: ALL(全表扫描)。你可以插个几百上千条数据再试试,大概率就会触发索引了。
3. 查询条件踩了索引失效的坑
这是最常见的情况,比如:
- 查询时给索引字段套了函数:
WHERE YEAR(age) = 1990,这种情况索引直接失效,优化器只能全表扫。 - 字段类型不匹配:比如你把
rating(整数)当成字符串查WHERE rating = '5',隐式类型转换会导致索引失效。 - 没用到联合索引的最左前缀:比如你建了
(rating, age)的联合索引,但查询只写了WHERE age > 25,索引也不会被触发。
4. 查询要返回所有字段,优化器觉得回表成本太高
如果你的查询是SELECT * FROM sailors WHERE age > 20;,哪怕你给age建了索引,优化器可能也会选择全表扫——因为走索引拿到sid后,还要回表去查sname、rating这些字段,要是符合条件的数据多,回表的成本比全表扫还高。这种情况可以试试覆盖索引,比如建(age, sname, rating),这样查询直接从索引里拿数据,不用回表,EXPLAIN就会显示走索引了。
最后提一句:你的查询语句很关键!
你没贴你跑的查询是什么,这对排查太重要了——比如如果是SELECT * FROM sailors;这种要返回全表的语句,不管你建什么索引,优化器都会选全表扫,因为没必要走索引。
内容的提问来源于stack exchange,提问作者ggghahaha
相关产品推荐
相关产品推荐

