mysql中的索引

发布时间 2023-11-26 14:13:11作者: 笑嘻嘻嘻了

mysql中索引的实现方式是什么?

利用B+树实现索引的。

数据库中的数据存储在磁盘上,使用的时候加载到存储引擎中的buffer pool(内存中的一个缓存池)中去;同理索引也是以文件的形式存储在磁盘上的,使用的时候加载到buffer pool中去。

注意:数据和索引都是以“页”的形式一页一页的加载进内存的(具体请看操作系统的内存管理中的页式内存)

B+树的特点:
非叶子节点只存在索引值和指向下一个子节点的指针,而叶子节点既包含索引值也包含具体的数据,且每个节点上的索引值都是按升序排序的

为什么使用使用B+树索引,而不使用二叉树(二叉搜索树、平衡二叉树等)、以及Hash索引?

  1. B+树 VS B树:

    • 由于B树的所有节点都包含索引值和具体的数据,所以相对而言B+树的单个非叶子节点所需要的空间更小,一次磁盘IO读进buffer pool的节点更多
    • B+树的叶子节点之间用双向链表的形式串起来了,使得B+树索引更适合范围查询
  2. B+树 VS 二叉树:

    • 二叉树中一个节点只有两个子节点,当数据量非常大的时候,二叉树的高度就会很高,导致二叉树一次查询会需要很多次的磁盘IO操作;而B+树不限制子节点的数量,能将树的高度一直维持在3~4层,一次IO查询只需要很少的磁盘IO操作
  3. B+树 VS 哈希索引:

    • 哈希索引在等值查询上能做到O(1)的时间复杂度
    • 但是哈希索引不适合做范围查询,因为哈希索引无序

什么时候适合使用索引进行查询?

  1. 字段具有唯一性

  2. 常用于where、order by、group by的字段

不适合使用索引进行查询的情况?

(由于索引的建立和管理是占用一定的开销的,所以在有些情况使用索引反而会降低性能)

  1. 字段不具有唯一性。如表中有个字段是性别,由于性别只有男女,如果对其建立索引查询时,只能分辨出男女两个范围,无法将数据进行更细力度的划分

  2. 不常用于where、order by、group by的字段

  3. 经常被修改的字段

  4. 表中的数据很少时

什么情况下索引会失效?

  1. 使用左模糊匹配或者左右模糊匹配

  2. 对索引字段使用了函数、计算表达式、类型转换

  3. 在联合索引时,没有遵循“最左匹配”的原则

  4. where子句进行条件查询时,若出现or关键字连接两个条件,且一个条件是索引字段,一个条件不是时会出现索引失效

有什么提高索引性能的方法?

  1. 使用前缀索引。前缀索引是指将字段的前几个字符作为索引,而不将整个字段作为索引。这样整个节点会消耗更小的空间,从而一个索引页中可以存储更多的索引项

  2. 使用覆盖索引。覆盖索引是指二级索引就能直接获取查询想要的字段,而不需要回表操作

  3. 使主键索引自增。主键值自增的话,在插入新数据时,只需要在主键索引B+树进行追加操作,而不需要重新移动其他节点

  4. 防止索引失效