MySQL索引为什么不生效:六个写法让EXPLAIN当场现形

来源:互联网 时间:2026-08-27

明明建了索引,查询还是全表扫描,几百万行的表一查十几秒。索引失效多数不是索引的问题,是SQL写法的问题。别猜,EXPLAIN一下,type列是不是ALL、key列是不是NULL,一目了然。

EXPLAIN SELECT * FROM orders WHERE DATE(create_time) = '2026-08-20';
-- type=ALL 全表扫描:函数包住了索引列,索引失效

EXPLAIN SELECT * FROM orders
WHERE create_time >= '2026-08-20 00:00:00'
AND create_time < '2026-08-21 00:00:00';
-- 改成范围写法,type=ref/range,索引正常

失效场景一共有几类常见的:索引列上套函数或做运算;like以百分号开头;隐式类型转换(varchar列用数字比较);联合索引不满足最左前缀;or两侧有一边没索引;负向条件not in、!=在多数场景放弃索引。

-- 隐式转换:user_id是varchar,传数字,索引失效
EXPLAIN SELECT * FROM users WHERE user_id = 10086;
EXPLAIN SELECT * FROM users WHERE user_id = '10086'; -- 加引号才走索引

-- 最左前缀:联合索引(a,b,c)
EXPLAIN SELECT * FROM t WHERE b = 1 AND c = 2; -- 不走,缺了a
EXPLAIN SELECT * FROM t WHERE a = 1 AND c = 2; -- 部分走(a)
EXPLAIN SELECT * FROM t WHERE a = 1 AND b = 2; -- 全走(a,b)

读EXPLAIN抓重点就行:type从好到差大致是const、eq_ref、ref、range、index、ALL,出现ALL就该处理;rows预估扫描行数过大也是信号;Extra里出现Using filesort和Using temporary说明排序临时表压力不小,多半要调整索引或写法。

养成习惯:上线的每条核心SQL先跑一遍EXPLAIN,慢查询日志里捞出来的语句逐条过。索引这东西建了不用白占写入性能,用了不生效等于没建,EXPLAIN是唯一裁判。

相关文章

标签:

A5创业网 版权所有

返回顶部