复合索引失效的常见情况

复合索引(也称为联合索引或多列索引)是由多个列组成的索引,当查询条件符合索引的最左前缀原则时,复合索引才能发挥最大作用。以下是复合索引失效的几种常见情况:
1. 不遵循最左前缀原则
复合索引按照定义的列顺序从左到右匹配,如果查询条件没有包含最左边的列,索引将失效。

-- 假设有复合索引 (col1, col2, col3)
-- 生效情况:
SELECT * FROM table WHERE col1 = 'a';
SELECT * FROM table WHERE col1 = 'a' AND col2 = 'b';
SELECT * FROM table WHERE col1 = 'a' AND col2 = 'b' AND col3 = 'c';
-- 失效情况:
SELECT * FROM table WHERE col2 = 'b'; -- 缺少col1
SELECT * FROM table WHERE col3 = 'c'; -- 缺少col1和col2

2. 中间列缺失
即使查询条件包含最左列,但如果跳过了中间的列,索引只能部分使用。

-- 索引 (col1, col2, col3)
SELECT * FROM table WHERE col1 = 'a' AND col3 = 'c';
-- 只能用到col1的索引,col3无法使用索引

3. 对索引列使用函数或运算
对索引列进行函数操作、计算或类型转换会导致索引失效。

-- 失效情况:
SELECT * FROM table WHERE YEAR(col1) = 2023;
SELECT * FROM table WHERE col1 + 1 = 10;
SELECT * FROM table WHERE CAST(col1 AS CHAR) = '100';

4. 使用范围查询后的列失效
当对索引列使用范围查询(>, <, LIKE, BETWEEN等)后,其后的索引列无法使用索引。

-- 索引 (col1, col2, col3) 
-- 部分失效情况: SELECT * FROM table WHERE col1 = 'a' AND col2 > 'b' AND col3 = 'c';
-- col1和col2能使用索引,但col3无法使用索引

5. 使用OR条件
如果OR条件中有一个列没有索引,整个查询将不使用索引。

-- 假设col1有索引,col4没有索引
SELECT * FROM table WHERE col1 = 'a' OR col4 = 'd'; -- 索引失效

6. 使用NOT、!=、<>操作符
这些否定操作符通常会导致索引失效。

SELECT * FROM table WHERE col1 != 'a'; -- 索引失效
SELECT * FROM table WHERE col1 NOT IN ('a', 'b'); -- 索引失效

7. LIKE以通配符开头

SELECT * FROM table WHERE col1 LIKE '%abc'; -- 索引失效
SELECT * FROM table WHERE col1 LIKE 'abc%'; -- 可以使用索引

8. 数据类型不匹配
隐式类型转换会导致索引失效。

-- 假设col1是varchar类型
SELECT * FROM table WHERE col1 = 123; -- 数字与字符串比较,索引失效

9. 索引列使用IS NULL或IS NOT NULL

SELECT * FROM table WHERE col1 IS NULL; -- 可能无法使用索引

10. 表数据量很小
当表中数据量很少时,优化器可能选择全表扫描而非使用索引。

优化建议
设计复合索引时,将选择性高的列放在前面

查询语句尽量符合最左前缀原则

避免对索引列进行计算或函数操作

对于范围查询,尽量放在复合索引的最后

考虑使用覆盖索引(查询列都在索引中)提高性能

理解这些索引失效场景可以帮助设计更有效的索引和编写更优化的SQL查询。

不同场景对比
查询条件 复合索引 索引使用情况
A,B,D (A,B,C) 部分使用(A,B)
A,B,D (A,B,D) 完全使用
A,B,D (A,D,B) 部分使用(A)
A,B,D (B,A,D) 可能使用(B,A)或全表扫描

版权声明:
作者:lhylwl
链接:http://ye-w.cn/2025/04/14/50.html
来源:小凡笔记-我的技术记录
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>