Skip to content

下面那些语句会用到索引?

约 831 字大约 3 分钟

MySQL京东

2025-03-25

⭐ 题目日期:

京东 - 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 列不会参与索引过滤,但索引会覆盖到 AB 的条件。

2. Select * from t where b > 5 and a = 3;

  • 索引使用情况
    使用索引 (A, B)
    • SQL 优化器会自动调整条件顺序,等价于 a=3 AND b>5,因此与第 1 条一致。
    • 结论:条件顺序不影响索引匹配,只要最左前缀存在。

3. Select * from t where a = 3 and b > 5 and c > 7;

  • 索引使用情况
    部分使用索引 (A, B),但 C 列失效。
    • A 是等值查询,B 是范围查询,此时索引会匹配到 A=3B>5 的记录,但 C>7 无法通过索引过滤。
    • 原因:一旦某列(如 B)使用范围查询,后续列(C)无法继续使用索引。

4. Select * from t where a < 3;

  • 索引使用情况
    使用索引 (A)
    • 最左列 A 是范围查询,索引会匹配 A<3 的所有记录,但 BC 无法参与索引过滤。

5. Select * from t where a <= 3;

  • 索引使用情况
    使用索引 (A)
    • 与第 4 条类似,A 是范围查询(<=),索引匹配逻辑相同。

索引失效与优化场景(字符串转数字问题)

如果字段 A 是字符串类型,但查询条件写为 a=3(数字),会导致 隐式类型转换,索引失效。
优化方法

  1. 确保比较双方类型一致(如 a='3')。
  2. 若无法修改查询,可考虑新增一个数值类型的冗余列并建立索引。

总结:索引使用规则

查询语句是否使用索引使用到的索引列原因
a=3 AND b>5A, B最左前缀 A 等值,B 范围
b>5 AND a=3A, B优化器重排条件为 a=3 AND b>5
a=3 AND b>5 AND c>7✅(部分)A, BB 是范围查询,C 无法继续使用索引
a<3A最左前缀 A 范围
a<=3Aa<3,范围查询

执行计划验证

建议通过 EXPLAIN 命令查看实际执行计划(关注 keykey_len 字段),例如:

EXPLAIN SELECT * FROM t WHERE a=3 AND b>5;

扩展:索引设计建议

  1. 范围查询尽量放在联合索引的最后一列,避免中断后续列的索引使用。
  2. 若需频繁使用 C 列过滤,可考虑单独建立索引 (A, C) 或调整联合索引顺序。
  3. 监控隐式类型转换问题,避免索引失效。