哪些情况会让SQL索引失效?

1、模糊匹配:当进行左模糊或全模糊查询时,例如 `like '%米'` 和 `like '%米%'`,索引通常不会被使用。

场景:

1)select * from user where name like '%米';

2)select * from user where name like '%米%';
2、隐式转换:如果查询条件中的数据类型与表中字段的数据类型不一致,可能会导致隐式类型转换,例如 `where name = 123` 或者 `join on` 关联字段数据类型不一致。

场景:

1)select * from user where name = 123;

2)select * from user a left join dept b on where a.userid = b.userid;//user表的userid是int类型,而dept表的userid是string类型
3、函数运算:在查询条件中使用函数运算时,索引不会被使用,例如 `where year(create_time) = '2024'`。

场景:select * from user where year(create_time) = '2024';
4、表达式运算:查询条件中包含表达式运算时,索引不会被使用,例如 `where id + 1 = 10`。

场景:select * from user where id + 1 = 10;
5、最左匹配原则:对于联合索引,如果不符合最左匹配原则,索引不会被使用,例如 `index(a,b,c) where a =1 and c =2`。

场景:

1)如果有一个 2 列的索引 (a, b),则已经对 (a)、(a, b) 上建立了索引;

2)如果有一个 3 列索引 (a, b, c),则已经对 (a)、(a, b)、(a, b, c) 上建立了索引。
6、OR操作:不当使用OR操作,可能会导致索引失效,例如 `where id > 1 or id > 10`。

场景:select * from user where id > 1 or id > 10;

### 三级标题:MySQL 中导致索引失效的常见原因 MySQL 中索引的使用对于查询性能至关重要。然而,在某些情况下,即使字段上建立了索引,查询仍然可能无法利用索引,导致性能下降。以下是常见的导致索引失效的原因: 1. **联合索引不满足最左匹配原则** 联合索引由多个字段组成,查询时必须遵循最左前缀原则,即查询条件必须包含联合索引中最左侧的字段,并且不能跳过中间的字段。例如,对于联合索引 `(name, age, classid)`,查询 `WHERE name = 'John'` 或 `WHERE name = 'John' AND age = 30` 可以使用索引,但 `WHERE age = 30` 或 `WHERE name = 'John' AND classid = 100` 则无法充分利用索引[^1]。 2. **模糊查询以 `%` 开头** `LIKE` 查询如果以通配符 `%` 开头,如 `LIKE '%x'` 或 `LIKE '%x%'`,则无法使用索引,因为索引结构无法支持从中间或结尾进行查找。而 `LIKE 'x%'` 这种以固定值开头的查询可以有效使用索引[^1]。 3. **索引列参与运算或使用函数** 如果查询条件中对索引列进行计算、函数处理或类型转换,会导致索引失效。例如,`WHERE age + 1 = 30` 或 `WHERE UPPER(name) = 'JOHN'` 都会使得数据库无法直接使用索引,而进行全表扫描[^1]。 4. **使用不等于 (`!=` 或 `<>`) 条件** 查询中使用 `!=` 或 `<>` 操作符时,MySQL 无法利用索引来优化查询,因为索引是基于精确匹配的结构,无法高效处理不等于的条件[^1]。 5. **使用 `IS NOT NULL` 或 `IS NULL` 条件** 尽管某些情况下 `IS NULL` 可以使用索引,但 `IS NOT NULL` 通常会导致索引失效。这是因为索引默认不包含 `NULL` 值,而 `IS NOT NULL` 需要扫描所有非空记录,无法高效利用索引。 6. **使用 `OR` 连接条件** 当查询中使用 `OR` 连接多个条件时,即使其中某个条件使用了索引,也可能导致整个查询不使用索引。例如,`WHERE name = 'John' OR age = 30` 可能不会使用索引,除非 `OR` 中的每个条件都单独建立了索引[^1]。 7. **查询优化器选择全表扫描** 在某些情况下,MySQL 查询优化器可能会判断使用索引的成本高于直接进行全表扫描,从而放弃使用索引。例如,当查询返回的数据量占表数据总量的较大比例时,优化器可能会选择全表扫描来提高效率。 8. **范围查询后无法使用后续列** 对于联合索引,如果查询中使用了范围条件(如 `<`, `>`, `BETWEEN AND`),则范围条件右边的列将无法使用索引。例如,对于联合索引 `(name, age)`,查询 `WHERE name > 'John' AND age = 30` 中,`age` 字段将无法使用索引。 9. **类型转换导致索引失效** 如果查询条件中的数据类型与索引列的数据类型不一致,MySQL 会进行隐式类型转换,从而导致索引失效。例如,对字符串类型的字段使用数字进行查询,如 `WHERE id = 123`(`id` 是 `VARCHAR` 类型),可能导致索引无法使用。 ### 示例代码 以下是一些可能导致索引失效SQL 查询示例: ```sql -- 1. 使用 LIKE '%x' 导致索引失效 EXPLAIN SELECT * FROM users WHERE name LIKE '%John'; -- 2. 索引列参与运算 EXPLAIN SELECT * FROM users WHERE age + 1 = 30; -- 3. 使用 OR 导致索引失效 EXPLAIN SELECT * FROM users WHERE name = 'John' OR age = 30; -- 4. 使用 != 导致索引失效 EXPLAIN SELECT * FROM users WHERE age != 30; -- 5. 使用 IS NOT NULL 导致索引失效 EXPLAIN SELECT * FROM users WHERE name IS NOT NULL; ``` 通过 `EXPLAIN` 命令可以查看这些查询的执行计划,确认是否使用了索引。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值