MySQL 索引失效场景

MySQL 索引失效场景
XRMySQL 索引失效场景
- 索引列参与计算或进行函数操作
- 使用OR,并且OR的两边存在< 或者 > 的时候
- 使用like操作,但是不满足左匹配,例如:”%java”
- 隐式类型转换,比如一个string类型列,使用数字来查询。这种情况有一个特列,如果字段类型为int类型,而查询条件添加了单引号或者双引号,则Mysql会参数转化为int类型,这种情况也可以走索引。
- 不等于比较。这种情况也是有可能会走索引的,比如用id进行!=,是可能走索引的。
- 使用is not null时不走索引,使用 is null 走索引
- order by。如果order by的时候数据量很小,数据库可能直接在内存中进行排序。
- in。一般在in中的值比较少的时候可能会走索引优化,但如果选项比较多,可能不走索引。
- 联合索引失效。比如联合索引(a,b,c),进行查询时没有满足最左匹配(查b,查c,查b c)
- 存储引擎不能使用索引范围条件右边的列
- 两列做比较。如果两个列数据都有索引,但是在查询条件中对两列数据进行了对比操作,则会导致索引失效。
- 查询条件是用no in时,如果是主键则走索引。如果是普通索引,则失效
- not exists 不走索引,exists 可能走索引
1. 索引列参与计算或函数操作
- 正常判断:索引列直接使用原始值。
- 失效原因:索引存储的是列原始值,计算或函数操作后生成的值无法匹配索引结构。
- 具体原理:B+ 树索引基于原始值构建,计算或函数会破坏值与索引的映射关系,导致无法通过索引树快速定位。
- 示例 SQL:
1 | -- 失效 |
2. 使用 OR 且两边存在范围查询
- 正常判断:
OR两侧均有索引且逻辑简单。 - 失效原因:
OR要求同时满足多个条件,若任意一侧无索引或涉及范围查询,优化器可能放弃索引。 - 具体原理:MySQL 对
OR的优化能力有限,若无法合并索引范围,则选择全表扫描。 - 示例 SQL:
1 | -- 失效(假设 d 列无索引) |
3. LIKE 不满足左匹配
- 正常判断:
LIKE使用前缀匹配(如'abc%')。 - 失效原因:以通配符开头(
%或_)破坏索引前缀有序性。 - 具体原理:B+ 树索引按前缀排序,无法反向或中间模糊匹配。
- 示例 SQL:
1 | -- 失效 |
4. 隐式类型转换
- 正常判断:查询值与列类型严格一致。
- 失效原因:类型不匹配导致 MySQL 隐式转换,破坏索引匹配。
- 具体原理:索引存储的是列定义的类型,隐式转换相当于对列使用函数(如
CAST)。 - 示例 SQL:
1 | -- 失效(假设 a 是 VARCHAR) |
5. 不等于比较(!= 或 <>)
- 正常判断:主键或唯一索引可能走索引。
- 失效原因:非主键的不等于操作需扫描大部分数据,优化器认为全表更快。
- 具体原理:索引适合定位少量数据,不等于操作需遍历索引树大部分节点。
- 示例 SQL:
1 | -- 失效(普通索引) |
6. IS NOT NULL 与 IS NULL
- 正常判断:
IS NULL可走索引,IS NOT NULL可能失效。 - 失效原因:
IS NOT NULL需遍历所有非空值,成本高。 - 具体原理:索引中
NULL值集中存储(InnoDB),IS NULL可快速定位,而IS NOT NULL需扫描全索引。 - 示例 SQL:
1 | -- 失效 |
7. ORDER BY 排序
- 正常判断:排序字段有索引且顺序一致。
- 失效原因:小数据量直接在内存排序;排序字段无索引或顺序不匹配。
- 具体原理:索引本身有序,若
ORDER BY字段与索引顺序一致,可避免filesort操作。 - 示例 SQL:
1 | -- 失效(无索引) |
8. IN 条件
- 正常判断:
IN列表较短且选择性高。 - 失效原因:长列表导致优化器认为全表扫描更快。
- 具体原理:
IN本质是多个OR,列表过长时索引检索成本超过全表扫描。 - 示例 SQL:
1 | -- 失效(列表过长) |
9. 联合索引未遵循最左前缀
- 正常判断:查询条件包含最左列且顺序合理。
- 失效原因:未包含最左列,或中间列被范围查询中断。
- 具体原理:联合索引按
(a, b, c)顺序构建 B+ 树,缺少中间列导致后续列无序。 - 示例 SQL:
1 | -- 失效(缺少 a) |
10. 范围查询阻断后续列
- 正常判断:范围查询列在联合索引末尾。
- 失效原因:范围查询(如
>、BETWEEN)后,后续列无法使用索引。 - 具体原理:范围查询导致索引后续列无序,无法通过 B+ 树快速定位。
- 示例 SQL:
1 | -- 仅 a 和 b 走索引,c 失效 |
11. 两列比较操作
- 正常判断:单列条件使用索引。
- 失效原因:索引不支持列间比较。
- 具体原理:索引存储列值与行位置的映射,无法直接比较两列值。
- 示例 SQL:
1 | -- 失效 |
12. NOT IN 条件
- 正常判断:主键
NOT IN可能走索引。 - 失效原因:普通索引需回表验证,优化器认为全表扫描更快。
- 具体原理:主键索引包含完整数据,普通索引需回表检查是否满足
NOT IN。 - 示例 SQL:
1 | -- 失效(普通索引) |
13. NOT EXISTS 子查询
- 正常判断:
EXISTS可能走索引,NOT EXISTS通常失效。 - 失效原因:
NOT EXISTS需逐行验证子查询,无法利用索引。 - 具体原理:子查询需全表扫描或全索引扫描,成本较高。
- 示例 SQL:
1 | -- 失效 |
评论
匿名评论隐私政策











