索引加速where查询需满足三前提:字段有索引、写法不破坏索引、执行计划实际使用;高频字段须手动建索引,单条件建单列索引,多条件按最左前缀原则建复合索引,低选择性字段单独建索引无效。

能用索引加速的 WHERE 查询,必须满足三个前提:字段上有索引、写法不破坏索引、执行计划里真用了它。 其他所有技巧都建立在这三点之上,缺一不可。
WHERE 条件字段没建索引,再怎么写都白搭
这是最常被忽略的第一步。数据库不会自动为所有列建索引,user_id、order_date、status 这类高频过滤字段,必须手动创建索引。
- 单条件查询优先建单列索引:
CREATE INDEX idx_user_id ON orders(user_id); - 多条件组合(如
WHERE user_id = ? AND order_date > ?)要建复合索引,且顺序关键:CREATE INDEX idx_user_date ON orders(user_id, order_date);——user_id必须放前面,否则order_date单独查就失效 - 低选择性字段(如
gender只有 'M'/'F')单独建索引意义不大,除非配合高选择性字段组成复合索引
这些写法会让索引直接失效
即使字段有索引,以下写法也会导致 MySQL 跳过索引、走全表扫描:
- 对索引列用函数:
WHERE YEAR(order_date) = 2023→ 改成WHERE order_date >= '2023-01-01' AND order_date - 隐式类型转换:
WHERE user_id = '100'(user_id是 INT)→ 字符串和数字比较会触发转换,改用WHERE user_id = 100 - LIKE 前导通配符:
WHERE name LIKE '%john'→ 索引完全无效;WHERE name LIKE 'john%'才能用上 - OR 连接未全部索引的字段:
WHERE user_id = 100 OR email = 'a@b.com',如果email没索引,整个条件大概率退化为全表扫描
用 EXPLAIN 验证索引是否真被用了
别猜,要看执行计划。运行 EXPLAIN SELECT ... WHERE ...,重点关注三列:
-
type:值为const、ref、range表示走了索引;ALL就是全表扫描 -
key:显示实际使用的索引名,为空说明没用索引 -
Extra:出现Using index表示覆盖索引(不用回表),是理想状态;出现Using where; Using filesort或Using temporary就得优化
特别注意:复合索引下,WHERE order_date > '2023-01-01' 单独使用时,idx_user_date 不会生效 —— 最左前缀没命中,这点极易被忽略。











