38 个 MySQL 索引核心问题:原理、失效场景与优化实战

MySQL 索引

1. 什么是索引?索引的本质、优缺点、底层逻辑

索引类似于书籍的目录,可以减少扫描的数据量,提高查询效率。

  • 如果查询的时候,没有用到索引就会全表扫描,这时候查询的时间复杂度是 O(N)
  • 如果用到了索引,那么查询的时候,可以基于二分查找算法,通过索引快速定位到目标数据, MySQL 索引的数据结构一般是 B+ 树,其搜索复杂度为 O(logdN),其中 d 表示节点允许的最大 子节点个数。

索引是数据库存储引擎用于快速查询数据的排序数据结构 ,本质是以空间换时间

  • 作用:避免全表扫描,减少磁盘随机 IO,大幅提升 SELECT、WHERE、ORDER BY、GROUP BY、JOIN 效率。

  • 优点:查询速度指数级提升,降低数据库 CPU 与 IO 压力。

  • 缺点:

    1. 占用额外磁盘空间,索引越大空间开销越高。
    2. INSERT/UPDATE/DELETE 时需同步维护所有索引,降低写入性能。
    3. 索引过多会导致优化器选择困难,甚至选错索引。
  • 适用场景:高频查询、大表、筛选性强的字段;不适用小表、重复度极高字段、频繁写入字段。

2. InnoDB 为什么选用 B+ 树作为索引结构,而不是 B 树、哈希、红黑树

  1. 红黑树:树太高,磁盘 IO 次数多,不适合磁盘存储。

  2. 哈希索引:仅支持等值查询,不支持范围、排序、模糊查询,限制极大。

  3. B 树:叶子节点不相连,范围查询需回溯父节点,效率低。

  4. B+ 树优势:

    • 非叶子节点只存键值,不存完整数据,单次 IO 加载更多索引项,树更矮更胖,IO 次数极少。
    • 所有数据都存在有序双向链表叶子节点,范围查询、分页、排序极快。
    • 查询复杂度稳定 O (log n),所有查询都走到叶子节点,性能稳定。
    • 适合磁盘预读特性,充分利用操作系统页缓存。

3. 聚簇索引 vs 非聚簇索引,InnoDB 与 MyISAM 索引差异

  • 聚簇索引

    索引结构与行数据物理存储在一起,叶子节点存储整行完整数据。

    InnoDB 主键索引就是聚簇索引,一个表只能有一个。

  • 非聚簇索引(二级索引)

    索引与数据分离,叶子节点只存主键值,查询需先查索引再回表查数据。

    InnoDB 的普通索引、唯一索引、联合索引都属于二级索引。

  • 引擎区别

    InnoDB:聚簇索引组织整张表,必须有主键,无主键会自动生成隐藏 rowid。

    MyISAM:索引与数据完全分离,所有索引都是非聚簇,叶子节点存数据行地址。

聚簇索引如何选择?

  1. 如果有主键,默认会使用主键作为聚簇索引的索引键(key);
  2. 如果没有主键,就选择第一个不包含 NULL 值的唯一列作为聚簇索引的索引键(key);
  3. 在上面两个都没有的情况下,InnoDB 将自动生成一个隐式自增 id 列作为聚簇索引的索引键 (key);

其它索引都属于辅助索引(Secondary Index),也被称为二级索引或非聚簇索引。创建的主键索引 和二级索引默认使用的是 B+Tree 索引。

4. 主键索引、唯一索引、普通索引、联合索引、全文索引区别与使用场景

  1. 主键索引(PRIMARY KEY)

    非空、唯一、不可重复,一个表只能一个,聚簇索引,性能最高。

  2. 唯一索引(UNIQUE)

    列值唯一,允许一个 NULL,约束性强,适合手机号、身份证。

  3. 普通索引(INDEX)

    仅加速查询,无约束,最常用。

  4. 联合索引

    多字段组合索引,遵循最左匹配,减少冗余索引,适合多条件组合查询。

  5. 全文索引(FULLTEXT)

    针对长文本高效搜索,支持 MATCH AGAINST,不支持模糊查询优化。

5. 最左匹配原则深度解析,包含范围查询、跳过字段、底层逻辑

联合索引是按字段顺序排序的,查询必须从左到右连续匹配,中断则后续字段无法使用索引。

例:索引 idx(a,b,c)

  • a=1 → 全命中

  • a=1 and b=2 → 全命中

  • a=1 and c=3 → 仅命中 a,c 失效

  • b=2 → 完全失效

  • a=1 and b>2 and c=3 → a、b 命中,c 失效(范围查询会中断后续匹配)

sql 复制代码
a=1 and b like 'xx%'

→ 仍可命中前两列

底层原因:B + 树按索引字段依次排序,不按最左开始就无法定位树节点。

6. 回表查询、覆盖索引、索引合并、索引排序深度解释

  • 回表:通过二级索引查到主键,再去聚簇索引查完整数据,多一次 IO,影响性能。

  • 覆盖索引:查询字段全部包含在索引中,无需回表,性能极高。

    例如:

    sql 复制代码
    select name from user where age=18

    索引(age,name)即为覆盖索引,因为查询的是name,在where子句里的是age。

  • 索引合并:MySQL 将多个单列索引结果合并,效率低于联合索引,尽量避免。

  • Using index:EXPLAIN 中出现代表使用覆盖索引,无回表。

  • Using filesort:无法用索引排序,需内存 / 磁盘排序,性能差。

7. 索引失效 12 种高频场景(深挖版)

  1. LIKE '%xxx' 左模糊,无法定位索引范围
  2. 索引列使用函数:DATE(create_time)、UPPER(name)
  3. 索引列运算:age+1、price*2
  4. 隐式类型转换:字符串字段传数字、数字字段传字符串
  5. 使用 !=、<>、NOT IN、NOT EXISTS、IS NOT NULL
  6. OR 连接条件中有非索引列
  7. 违反最左匹配原则
  8. 优化器判断全表更快(小表、索引选择性极差)
  9. ORDER BY 字段与索引顺序不一致
  10. GROUP BY 无法使用索引排序
  11. JOIN 关联字段类型、字符集不一致
  12. 使用 SELECT * 导致无法使用覆盖索引

8. 索引选择性是什么?为何决定索引效率?如何计算?

索引选择性 = 不重复值数量 / 表总行数,值越接近 1 效率越高。

  • 高选择性:身份证、手机号、订单号,索引过滤性极强。
  • 低选择性:性别、状态(0/1),索引几乎无效,优化器会直接全表扫描。
  • 计算:SELECT COUNT(DISTINCT column)/COUNT(*) FROM table;
  • 结论:选择性极低的字段不要建索引,浪费空间且拖慢写入。

9. EXPLAIN 执行计划全字段解析

  • id:查询执行顺序,id 越大越先执行。

  • select_type:SIMPLE 简单查询、SUBQUERY 子查询、DERIVED 派生表。

  • table:操作表。

  • type:索引效率(从优到劣)

    sql 复制代码
    system > const > eq_ref > ref > range > index > ALL

    ALL = 全表扫描,必须优化。

  • key:实际使用索引,NULL = 未命中。

  • key_len:索引使用长度,可判断联合索引是否用满。

  • rows:预估扫描行数,越小越好。

  • Extra:

    Using index = 覆盖索引;

    Using filesort = 文件排序需优化;

    Using temporary = 临时表需优化;

    Using where = 使用 where 过滤。

10. 为什么强烈推荐自增主键,不推荐 UUID、随机字符串

  1. 自增 ID 顺序插入,B + 树叶子节点顺序追加,无页分裂、无数据迁移,写入性能极高。
  2. 主键长度小,二级索引叶子节点存主键更小,节省大量空间。
  3. UUID 无序、长度长,插入频繁导致页分裂、节点碎片,查询性能大幅下降。
  4. 无序主键会导致索引树频繁调整,缓存命中率降低。
  5. InnoDB 按主键聚簇,顺序主键范围查询更快。

11. 前缀索引原理、使用规则、优缺点、如何选择长度

对字符串前 N 个字符建立索引,减少索引体积。

  • 适用场景:长字符串 URL、邮箱、详情内容。

  • 选择长度:

    测试选择性,

    sql 复制代码
    SELECT COUNT(DISTINCT LEFT(col, N))/COUNT(*)

    接近全列选择性即可。

  • 优点:索引更小,写入更快,内存命中率更高。

  • 缺点:

    无法使用覆盖索引;

    无法完成索引排序;

    区分度不足会导致回表增加。

12. 索引下推 ICP(Index Condition Pushdown)原理与作用

MySQL 5.6+ 支持的优化机制,在索引层直接过滤不符合条件的数据,减少回表次数。

例:select * from user where name like 'L%' and age=20;

  • 无 ICP:先通过 name 查索引得到主键,回表查询所有行再判断 age。
  • 有 ICP:在索引节点直接判断 age 条件,过滤无效数据后再回表。
  • 默认开启:show variables like 'optimizer_switch';
  • 优势:大幅减少回表 IO,提升组合条件查询效率。

13. 什么是页分裂、页合并?对索引性能的影响

InnoDB 数据按页(16KB)存储,索引也是按页管理。

  • 页分裂:插入无序数据导致索引页满,分裂成新页,数据离散,查询 IO 增加。

  • 页合并:删除数据导致页过空,后台合并页,消耗资源。

  • 影响:

    频繁页分裂会导致索引碎片、查询变慢、空间浪费。

  • 避免:使用自增主键、避免随机 ID 插入、定期 OPTIMIZE TABLE 整理碎片。

14. 索引碎片产生原因、危害、清理方法

  • 产生:大量 UPDATE/DELETE/ 随机 INSERT 导致页分裂、空间空洞。

  • 危害:查询扫描更多页,IO 上升,速度变慢,空间浪费。

  • 查看:SHOW TABLE STATUS LIKE 'table_name';

  • 清理:

    1. OPTIMIZE TABLE(InnoDB 实际重建表 + 索引)
    2. 导出数据→重建表→导入
    3. 业务低峰期执行,避免锁表影响线上

15. 企业级索引设计最佳实践(面试官最爱问的总结题)

  1. 只为高频查询、高选择性字段建索引。
  2. 多用联合索引,少建单列索引,避免冗余。
  3. 联合索引区分度高字段放左侧,满足最左匹配。
  4. 尽量设计覆盖索引,避免回表。
  5. 禁止在索引列使用函数、运算、隐式转换。
  6. 控制单表索引数量,一般3~5 个最佳。
  7. 大字符串使用前缀索引降低空间占用。
  8. 避免 SELECT *,只查业务需要字段。
  9. 小表、低选择性字段不建索引。
  10. 定期通过 EXPLAIN 优化慢查询,删除无用索引。
  11. 优先自增主键,杜绝无序 UUID。
  12. 联表查询保证关联字段类型、字符集、索引一致

16. B 树和 B+ 树的核心区别是什么?为什么 InnoDB 选择 B+ 树?

  • B 树:所有节点(叶子 + 非叶子)都存储数据;叶子节点互不相连;范围查询需要回溯父节点。
  • B+ 树 :只有叶子节点存储完整数据 ,非叶子节点只存索引键,用于导航;所有叶子节点由双向链表连接。

InnoDB 选择 B+ 树的原因:

  1. 非叶子节点不存数据,单个页面能容纳更多索引项,树更矮胖,磁盘 IO 次数更少。
  2. 叶子节点链表结构,对 ORDER BYBETWEEN><范围查询极其友好
  3. 查询复杂度稳定为 O (log n),任何查询都必须走到叶子节点,性能更可预测。
  4. 更适配磁盘预读特性,充分利用页缓存,整体 IO 效率远高于 B 树。

17. B+ 树高度一般有多高?千万级大表索引通常几层?

InnoDB 默认页大小 16KB。以 BIGINT 主键(8 字节)+ 指针(6 字节)为例,一个非叶子节点大约可存放 1170 个键。

  • 1 层 B+ 树:仅叶子节点,存少量数据。
  • 2 层 B+ 树:可支持约 1170 × 约 16KB 数据量。
  • 3 层 B+ 树:可支持 1170×1170 ≈ 136 万条数据。
  • 4 层 B+ 树:可支持上亿甚至十几亿条数据。

实际工程中,千万级数据表的 B+ 索引高度通常只有 2~3 层,意味着一次查询最多 2~3 次磁盘 IO,效率极高。


18. B+ 树的叶子节点为什么要设计成双向链表?

主要为了支持高效的范围查询与排序

  1. 找到起始叶子节点后,可以直接沿着链表顺序遍历,无需回溯上层节点。
  2. 天然支持 ORDER BYGROUP BYLIMIT 分页、BETWEEN ... AND ... 等业务常用逻辑。
  3. 双向链表支持正向、反向遍历,实现 ASC/DESC 排序成本极低。
  4. 可以实现顺序 IO,比随机 IO 快一个数量级。

如果没有这条链表,范围查询会退化为多次随机 IO,性能会大幅下降。


19. 为什么说 B+ 树是专为磁盘设计的数据结构?

磁盘访问速度远低于内存,数据库索引设计核心目标是减少磁盘 IO 次数

B+ 树完全贴合磁盘特性:

  1. 矮胖结构:层级少,IO 次数极少。
  2. 节点大小对齐磁盘页:16KB 刚好匹配操作系统与 InnoDB 页大小,充分利用预读。
  3. 顺序 IO 友好:叶子链表连续遍历,充分发挥磁盘顺序读写优势。
  4. 稳定的查找路径:所有查询都走到叶子,不会出现极端慢查询。
  5. 对缓存友好:非叶子节点常驻内存概率高,进一步降低 IO。

20. 聚簇索引和二级索引的 B+ 树结构有什么不同?

  • 聚簇索引(主键索引)B+ 树

    叶子节点存储的是整行完整数据,查到叶子就拿到了所有字段,不需要再回表。

  • 二级索引(普通 / 联合 / 唯一索引)B+ 树

    叶子节点只存储索引列 + 主键值,不存整行数据。

    查询流程是:

    二级索引树 → 找到主键 → 再去聚簇索引树查完整数据 → 即回表查询

这也是为什么二级索引查询通常比主键查询慢的根本原因。


21. B+ 树的页分裂、页合并是什么?对性能有什么影响?

InnoDB 以页(16KB)为单位管理索引与数据。

  • 页分裂:插入数据时,索引页已满,会分裂成两个新页,重新平衡树结构。
  • 页合并:删除数据后,页面过空,InnoDB 会将相邻页合并,回收空间。

影响:

  1. 频繁分裂、合并会产生索引碎片,导致查询 IO 变多、速度变慢。
  2. 自增主键插入是顺序追加,几乎不触发页分裂,性能极高。
  3. UUID、随机 ID 插入会频繁引发页分裂,写入性能急剧下降。
  4. 碎片过多会导致索引占用空间变大、缓存命中率下降。

22. 为什么不推荐用 UUID 做主键,而推荐自增 ID?

UUID 的全称是 Universally Unique Identifier(通用唯一识别码)。

简单理解,它就是一个通过算法生成的、全球唯一的字符串(或数字),通常用来作为数据库记录的唯一标识。

  1. 自增 ID 是有序的,插入时只在 B+ 树尾部追加,几乎无页分裂,写入性能高。
  2. 自增 ID 长度小(BIGINT 8 字节),二级索引存储压力小,节省大量空间。
  3. UUID 无序、长度长(36 字节),插入时随机分布,导致频繁页分裂、索引碎片严重。
  4. 无序主键会破坏聚簇索引的顺序性,范围查询、分页查询性能变差。
  5. 更长的主键会让所有二级索引同步变大,内存、磁盘成本翻倍。

23. B+ 树索引与哈希索引的区别,各自适用场景?

  • B+ 树索引

    支持等值查询、范围查询、排序、分组、模糊查询 like 'prefix%'

    适用:绝大多数业务查询场景,是 InnoDB 默认索引。

  • 哈希索引

    仅支持精准等值查询=IN),不支持任何范围、排序、模糊查询。

    适用:Memory 引擎、精确匹配极高的场景。

InnoDB 只有自适应哈希索引,不能手动建哈希索引,因为业务上范围、排序需求远多于纯等值查询。


24. 什么是全索引扫描(type: index)?和全表扫描有什么区别?

全索引扫描是遍历整个索引 B+ 树的叶子节点链表,而不是遍历数据表。

出现场景:

  • 查询没有 WHERE 条件,但需要遍历索引
  • COUNT(*) 走了二级索引
  • 违反最左匹配,但仍可以通过索引覆盖完成查询

与全表扫描(ALL)区别:

  1. index 只遍历索引,数据量更小;ALL 遍历整表数据。
  2. index 顺序 IO 更快;ALL 可能产生更多随机 IO。
  3. index 效率优于 ALL,但仍属于需要优化的类型。

25. B+ 树查找一条数据的完整流程是怎样的?

  1. 从 B+ 树根节点开始加载到内存。
  2. 在节点内部通过二分查找,定位到下一层子节点指针。
  3. 加载对应子节点,重复二分查找步骤。
  4. 一直向下,直到到达叶子节点
  5. 如果是聚簇索引:直接读取叶子节点上的完整数据。
  6. 如果是二级索引:拿到主键值,再回到聚簇索引执行一遍查找流程,即回表。

整个过程路径极短、IO 极少,这是索引能大幅提速的根本原因。

26. 什么是联合索引?为什么实际开发中优先推荐联合索引,而不是多个单列索引?

答案

联合索引是指将多个字段组合在一起建立一个索引 ,例如 idx(a, b, c)

优先使用联合索引的原因:

  1. 筛选效率更高

    多条件查询时,联合索引能一次性通过多个字段缩小数据范围,过滤性远强于多个单列索引。

  2. 避免索引合并

    多个单列索引在多条件查询时,MySQL 可能会使用索引合并(index merge),但效率远低于一个设计良好的联合索引。

  3. 节省空间

    一个联合索引占用空间远小于多个独立单列索引之和,减少磁盘和内存开销。

  4. 更容易实现覆盖索引

    联合索引天然包含多个字段,更容易让查询字段全部落在索引内,避免回表。

  5. 优化排序

    联合索引本身有序,可以直接用于

    sql 复制代码
    ORDER BY a, b

    这类排序,避免 Using filesort。


27. 详细解释联合索引的最左匹配原则,底层原理是什么?

最左匹配原则:使用联合索引 idx(a,b,c) 时,查询条件必须从左到右连续匹配索引字段,不能跳过左边字段直接查右边,否则后面字段无法使用索引。

底层原理:

联合索引在 B+ 树中的存储规则是:

  • 先按第一个字段 a 排序;
  • a 相等时,再按第二个字段 b 排序;
  • b 相等时,再按第三个字段 c 排序。

整个索引树是按左侧字段有序组织的。如果不从最左开始查,就无法在 B+ 树中进行二分查找定位,只能遍历索引或全表。


28. 联合索引中出现范围查询(>、<、between、like 'prefix%'),为什么会导致后面字段索引失效?

idx(a, b, c) 为例:

sql 复制代码
where a = 1 and b > 100 and c = 3;
  • a 是等值匹配,可以快速定位到一组节点;
  • b 是范围查询,会确定一段区间;
  • 但在这段区间内,c无序的,因为 B+ 树只在 b 相同的情况下才对 c 排序。

所以优化器只会使用到 a、bc 无法走索引。

结论:等值条件放前面,范围条件放最后,否则会截断后面字段的索引。


29. 联合索引的字段顺序如何设计?有什么通用原则?

答案

经典设计原则:等值在前,范围在后;区分度高在前,常用排序在前。

  1. 等值查询字段放最前面

    user_id = ?,能最快缩小范围。

  2. 区分度(选择性)高的字段靠前

    如订单号、手机号 > 状态、类型。

  3. 范围查询字段放最后

    因为范围会截断索引,后面字段失效。

  4. 排序、分组字段放入索引

    ORDER BYGROUP BY直接使用索引有序性,避免文件排序。

  5. 查询频次高的组合优先建索引

    避免为极少出现的查询建索引。

示例:

sql 复制代码
where a=? and b=? and create_time between ? and ?

索引顺序:(a, b, create_time)


30. 联合索引 (a,b,c),哪些 SQL 能命中索引?哪些不能?(高频面试题)

答案

索引:idx(a,b,c)

能命中(全部或部分)

  • where a = 1
  • where a = 1 and b = 2
  • where a = 1 and b = 2 and c = 3
  • where a = 1 and c = 3 (只命中 a,c 失效)
  • where a = 1 and b > 2 (命中 a、b,c 失效)
  • where a = 1 and b like 'abc%'

完全不能命中

  • where b = 2
  • where c = 3
  • where b = 2 and c = 3
  • where a like '%abc'

31. 联合索引和多个单列索引,在什么场景下效果差别巨大?

  1. 多条件组合查询

    联合索引一次定位;单列索引需要分别查找再合并,效率低很多。

  2. 需要排序

    联合索引天然有序,可以避免 Using filesort;单列索引做不到。

  3. 需要覆盖索引

    联合索引可直接覆盖查询字段;单列索引很难做到。

  4. 表数据量大、筛选压力高

    单列索引过滤后仍有大量数据,联合索引能大幅减少回表。

只有在每个字段都是独立等值查询、互无关联时,单列索引才勉强可用。

只要是组合查询 + 排序 + 分页,联合索引完胜。


32. 什么是联合索引的 "索引覆盖"?为什么它能极大提升性能?

查询所需的所有字段都包含在联合索引中,不需要回表查聚簇索引,就是覆盖索引。

例如:

索引 idx(a,b,c)

sql 复制代码
select b,c from t where a=1;

性能提升原因:

  1. 省去回表操作,减少一次 B+ 树查找;
  2. 只访问索引页,不访问数据页,IO 大幅减少;
  3. 数据更紧凑,缓存命中率更高;
  4. EXPLAIN 中会出现 Using index,代表最优状态。

33. 联合索引存在哪些常见坑?

  1. 字段顺序乱建

    范围在前、区分度低在前,导致索引利用率极低。

  2. 索引字段过多

    超过 3~4 个后,索引体积变大,写入性能下降明显。

  3. 重复冗余索引已有 (a,b,c),又建 (a)(a,b),浪费空间。

  4. 认为有索引就一定快?选择性极差的字段(如 status=0/1)放前面,索引形同虚设。

  5. 忽略排序字段与索引顺序不一致 导致出现 Using filesort。

  6. 使用 select *无法使用覆盖索引,必回表。


34. 已有联合索引 (a,b),还有必要单独建 (a) 索引吗?

完全没必要,属于冗余索引。

因为最左匹配原则:

  • 查询 where a=? 可以直接复用 (a,b) 索引;
  • 单独建 (a) 只会增加写入开销,不提升查询效率;
  • MySQL 优化器会自动选择更合适的索引,不会因为多建单列索引变快。

同理:

已有 (a,b,c),不需要再建 (a)(a,b)


35. 联合索引如何判断是否被充分使用?(结合 EXPLAIN)

主要看 key_lentypeExtra

  1. key_len

    表示实际使用的索引长度。

    • 长度等于整个联合索引长度:全部字段命中;
    • 长度只等于前几个字段:后面字段因范围查询或中断而失效。
  2. type

    • ref:等值匹配,索引使用良好;
    • range:范围查询,索引被截断;
    • index:全索引扫描,索引设计不合理。
  3. Extra

    • Using index:覆盖索引,最优;
    • Using where:在存储引擎过滤后,再次在 server 层过滤;
    • Using filesort / Using temporary:索引未覆盖排序,需要优化。

36. 如果有一个字段statue(1/0),那么他适合建索引吗?

不适合。区分度低的字段不适合建索引!!!

37. 索引的优缺点

索引最大的好处就是提高查询速度,但是索引也有缺点,比如:

  1. 需要占用物理空间,数量越大,张勇空间越大。
  2. 创建索引和维护索引需要耗费时间,这种时间随着数据量的增加而增大。
  3. 会降低表的增删改的效率,因为每次增删改索引,B+树为了维护索引的有序性,都需要来动态维护树的平衡。

所以,索引不是万能钥匙,他也是根据场景来使用的

38. 索引优化详细讲讲

常见优化索引的方法:

  1. 前缀索引优化

    使用前缀索引是为了减小索引字段大小,可以增加一个索引页中存储的索引值,有效提高索引的查询速度。在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。

  2. 覆盖索引优化

    覆盖索引是指 SQL 中 query 的所有字段,在索引 B+Tree 的叶子节点上都能找得到的那些索引,从二级索引中查询得到记录,而不需要通过聚簇索引查询获得,因此可以避免回表的操作。

  3. 主键索引最好是自增的

    • 如果我们使用自增主键,那么每次插入的新数据就会按顺序添加到当前索引节点的位置,不需要移动已有的数据,当页面写满,就会自动开辟一个新页面。因为每次插入一条新记录,都是追加操作,不需要重新移动数据,因此这种插入数据的方法效率非常高。

    • 如果我们使用非自增主键,由于每次插入主键的索引值都是随机的,因此每次插入新的数据时,就可能会插入到现有数据页中间的某个位置,这将不得不移动其它数据来满足新数据的插入,甚至需要从一个页面复制数据到另外一个页面,我们通常将这种情况称为页分裂。页分裂还有可能会造成大量的内存碎片,导致索引结构不紧凑,从而影响查询效率。

防止索引失效:

  • 当我们使用左或者左右模糊匹配的时候,也就是 like % xx 或者 like % xx% 这两种方式都会造成索引失效;
  • 当我们在查询条件中对索引列做了计算、函数、类型转换操作,这些情况下都会造成索引失效;
  • 联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。
  • 在 WHERE 子句中,如果 OR 连接的条件里有任何一个没有建立索引,通常就会导致索引失效、走全表扫描(和前后顺序无关)。MySQL 5.1 起引入了 index_merge 优化,当满足条件时优化器可能会对多个索引做合并(union /intersect)读取,但并不总是生效,依赖具体数据分布与优化器成本估算。
相关推荐
爱莉希雅&&&2 小时前
MySQL MGR 组复制 完整笔记
linux·数据库·笔记·mysql·mgr·数据库同步
m0_493934532 小时前
C#怎么实现EF Core全局查询过滤 C#如何用HasQueryFilter配置全局过滤条件自动排除已删除数据【数据库】
jvm·数据库·python
weixin_568996062 小时前
处理大体积DBF文件导入卡顿怎么办_性能优化与分批操作
jvm·数据库·python
m0_640309302 小时前
如何处理SQL查询中的逻辑重叠:AND OR嵌套优先级
jvm·数据库·python
qq_432703662 小时前
如何快速定位SQL表中的特定行:ROWID与唯一键的应用
jvm·数据库·python
m0_377618232 小时前
mysql如何配置插件以提升查询性能_安装启用memcached插件
jvm·数据库·python
djjdjdjdjjdj2 小时前
SQL高效实现两表数据对比_利用FULL OUTER JOIN查找差异
jvm·数据库·python
qq_424098562 小时前
html标签怎么表示用户输入_kbd标签键盘快捷键标注【介绍】
jvm·数据库·python
qq_372154232 小时前
PHP 中使用 GnuPG 实现 PGP 加密与解密的完整实践指南
jvm·数据库·python