外观
下面那些语句会用到索引?
⭐ 题目日期:
京东 - 2024/12/26 题目描述:
Where 字符串转成数字作比较,索引失效后怎么优化
t表有3个字段,A,B,C建了联合索引(A,B,C)
Select * from t where a = 3 and b > 5;
Select * from t where b > 5 and a = 3;
Select * from t where a = 3 and b > 5 and c > 7;
Select * from t where a < 3;
Select * from t where a <= 3;
📝 题解:
以下是针对各个 SQL 查询是否使用联合索引 (A, B, C) 的分析及优化建议:
1. Select * from t where a = 3 and b > 5;
- 索引使用情况:
✅ 使用索引 (A, B)。- 联合索引最左列
A
是等值查询,第二列B
是范围查询,此时索引会匹配到A=3
的所有记录,并按B>5
过滤。 - 注意:
C
列不会参与索引过滤,但索引会覆盖到A
和B
的条件。
- 联合索引最左列
2. Select * from t where b > 5 and a = 3;
- 索引使用情况:
✅ 使用索引 (A, B)。- SQL 优化器会自动调整条件顺序,等价于
a=3 AND b>5
,因此与第 1 条一致。 - 结论:条件顺序不影响索引匹配,只要最左前缀存在。
- SQL 优化器会自动调整条件顺序,等价于
3. Select * from t where a = 3 and b > 5 and c > 7;
- 索引使用情况:
✅ 部分使用索引 (A, B),但C
列失效。A
是等值查询,B
是范围查询,此时索引会匹配到A=3
且B>5
的记录,但C>7
无法通过索引过滤。- 原因:一旦某列(如
B
)使用范围查询,后续列(C
)无法继续使用索引。
4. Select * from t where a < 3;
- 索引使用情况:
✅ 使用索引 (A)。- 最左列
A
是范围查询,索引会匹配A<3
的所有记录,但B
和C
无法参与索引过滤。
- 最左列
5. Select * from t where a <= 3;
- 索引使用情况:
✅ 使用索引 (A)。- 与第 4 条类似,
A
是范围查询(<=
),索引匹配逻辑相同。
- 与第 4 条类似,
索引失效与优化场景(字符串转数字问题)
如果字段 A
是字符串类型,但查询条件写为 a=3
(数字),会导致 隐式类型转换,索引失效。
优化方法:
- 确保比较双方类型一致(如
a='3'
)。 - 若无法修改查询,可考虑新增一个数值类型的冗余列并建立索引。
总结:索引使用规则
查询语句 | 是否使用索引 | 使用到的索引列 | 原因 |
---|---|---|---|
a=3 AND b>5 | ✅ | A, B | 最左前缀 A 等值,B 范围 |
b>5 AND a=3 | ✅ | A, B | 优化器重排条件为 a=3 AND b>5 |
a=3 AND b>5 AND c>7 | ✅(部分) | A, B | B 是范围查询,C 无法继续使用索引 |
a<3 | ✅ | A | 最左前缀 A 范围 |
a<=3 | ✅ | A | 同 a<3 ,范围查询 |
执行计划验证
建议通过 EXPLAIN
命令查看实际执行计划(关注 key
和 key_len
字段),例如:
EXPLAIN SELECT * FROM t WHERE a=3 AND b>5;
扩展:索引设计建议
- 范围查询尽量放在联合索引的最后一列,避免中断后续列的索引使用。
- 若需频繁使用
C
列过滤,可考虑单独建立索引(A, C)
或调整联合索引顺序。 - 监控隐式类型转换问题,避免索引失效。