EXPLAIN 显示 type=ALL 需警惕,表示全表扫描;主因是索引失效,如函数操作、隐式转换、前导通配符等,而非数据量大。

为什么 EXPLAIN 显示 type=ALL 就得警惕
这代表 MySQL 正在对整张表逐行检查,哪怕只查 1 条数据。常见诱因不是数据量大,而是查询条件没走索引——比如对字段用了函数、隐式类型转换,或 WHERE 里写了 IS NULL 却没对应索引。
- 用
EXPLAIN SELECT ...看key列是否为NULL,是就说明没命中索引 -
possible_keys有值但key是NULL,大概率是索引失效,不是没建索引 - 注意
Extra列出现Using filesort或Using temporary,往往伴随全表扫描,别只盯type
哪些写法会悄悄让索引失效
不是加了索引就万事大吉。MySQL 对索引的使用很“死板”,稍不注意,优化器就放弃走索引。
-
WHERE name LIKE '%abc':前导通配符直接废掉 B+ 树的有序性 -
WHERE DATE(create_time) = '2024-01-01':对列用函数,索引无法比较 -
WHERE user_id = '123'(user_id是INT):字符串和数字比较触发隐式转换,索引失效 -
WHERE status != 1:范围不等于操作通常不走索引,尤其当status区分度低时
复合索引怎么建才真正生效
顺序决定一切。MySQL 只能按最左前缀匹配,且范围查询(>、BETWEEN、LIKE 'abc%')后面的字段不再用于索引查找。
- 查询是
WHERE a = 1 AND b > 10 AND c = 5,索引应建为(a, b, c),不是(a, c, b) -
ORDER BY a DESC, b ASC在 8.0+ 支持混合排序方向,但老版本只认统一方向,否则可能退化为文件排序 - 避免冗余索引:
(a)和(a, b)同时存在时,前者基本无用,还拖慢写入
小表要不要加索引、大表加索引卡住怎么办
“小表不用索引”是典型误解。只要查询频繁、有筛选条件,哪怕几千行也值得加索引;而大表加索引失败,往往卡在元数据锁或磁盘 I/O。
- 加索引前先确认没有长事务:
SELECT * FROM information_schema.INNODB_TRX查阻塞源 - 线上大表推荐用
ALGORITHM=INPLACE(5.6+),但注意它仍需排他 MDL 锁,DDL 期间不能改表结构 - 如果
ALTER TABLE卡住超 30 秒,优先查SHOW PROCESSLIST里有没有Waiting for table metadata lock
索引不是越多越好,但漏掉一个关键查询路径,就可能让某条慢查稳居 QPS 前三。最麻烦的永远不是“没加索引”,而是“加了但没被用上”。










