直接看
EXPLAIN输出中的 key 和 rows 字段,就能快速判断索引是否被 MySQL 用上。
用 EXPLAIN 查看执行计划
在 SQL 查询前加上
EXPLAIN(或
EXPLAIN FORMAT=TRADITIONAL),MySQL 会返回查询的执行计划,不真正执行语句。 key 列显示实际使用的索引名;如果为
NULL,说明没走索引 type 列反映访问类型,
const/
ref/
range通常表示走了索引,
ALL表示全表扫描 rows 是 MySQL 预估需要扫描的行数;数值越小,索引效果越好(注意:这是预估值,不一定等于实际扫描行数) Extra 列出现
Using index表示覆盖索引(只查索引就拿到结果),出现
Using filesort或
Using temporary往往意味着排序/分组没走索引,性能可能较差
检查 WHERE 条件是否符合最左前缀原则
复合索引(如
(a,b,c))只有满足最左前缀才能生效: ✅
WHERE a = 1、
WHERE a = 1 AND b = 2、
WHERE a = 1 AND b = 2 AND c = 3可用索引 ❌
WHERE b = 2、
WHERE c = 3、
WHERE b = 2 AND c = 3无法使用该索引(除非有单独为 b 或 c 建的索引) ⚠️
WHERE a = 1 AND c = 3只能用上 a,c 条件会回表过滤,不是“跳过 b”——b 不在条件中时,后续字段失效
留意隐式类型转换和函数操作
这些写法会让索引完全失效:
字段是字符串类型,但查询时写成WHERE col = 123(没加引号),触发隐式转换 对索引列使用函数:
WHERE YEAR(create_time) = 2023→ 改用范围查询:
WHERE create_time >= '2023-01-01' AND create_time用
LIKE时以通配符开头:
WHERE name LIKE '%abc'无法走索引;
WHERE name LIKE 'abc%'可以 使用
!=、
NOT IN、
OR(多个非同索引字段)也可能导致索引失效,需结合
EXPLAIN确认
验证真实执行效果:用慢查询日志或 performance_schema
EXPLAIN是预估,有时优化器选择未必符合预期。进一步验证可: 开启慢查询日志,设置
long_query_time = 0,捕获所有查询,观察
rows_examined实际扫描行数 用
SELECT @@last_insert_id或
SELECT SLEEP(0.001)搭配
SHOW PROFILE(已弃用)或 performance_schema 的
events_statements_history_long查看真实 I/O 和扫描量 执行
FLUSH STATUS;后运行查询,再查
SHOW STATUS LIKE 'Handler_read%';:若
Handler_read_key增加多、
Handler_read_rnd_next少,说明索引利用充分
