mysql中索引的实现方式是什么?
利用B+树实现索引的。
数据库中的数据存储在磁盘上,使用的时候加载到存储引擎中的buffer pool(内存中的一个缓存池)中去;同理索引也是以文件的形式存储在磁盘上的,使用的时候加载到buffer pool中去。
注意:数据和索引都是以“页”的形式一页一页的加载进内存的(具体请看操作系统的内存管理中的页式内存)
B+树的特点:
非叶子节点只存在索引值和指向下一个子节点的指针,而叶子节点既包含索引值也包含具体的数据,且每个节点上的索引值都是按升序排序的
为什么使用使用B+树索引,而不使用二叉树(二叉搜索树、平衡二叉树等)、以及Hash索引?
-
B+树 VS B树:
- 由于B树的所有节点都包含索引值和具体的数据,所以相对而言B+树的单个非叶子节点所需要的空间更小,一次磁盘IO读进buffer pool的节点更多
- B+树的叶子节点之间用双向链表的形式串起来了,使得B+树索引更适合范围查询
-
B+树 VS 二叉树:
- 二叉树中一个节点只有两个子节点,当数据量非常大的时候,二叉树的高度就会很高,导致二叉树一次查询会需要很多次的磁盘IO操作;而B+树不限制子节点的数量,能将树的高度一直维持在3~4层,一次IO查询只需要很少的磁盘IO操作
-
B+树 VS 哈希索引:
- 哈希索引在等值查询上能做到O(1)的时间复杂度
- 但是哈希索引不适合做范围查询,因为哈希索引无序
什么时候适合使用索引进行查询?
-
字段具有唯一性
-
常用于where、order by、group by的字段
不适合使用索引进行查询的情况?
(由于索引的建立和管理是占用一定的开销的,所以在有些情况使用索引反而会降低性能)
-
字段不具有唯一性。如表中有个字段是性别,由于性别只有男女,如果对其建立索引查询时,只能分辨出男女两个范围,无法将数据进行更细力度的划分
-
不常用于where、order by、group by的字段
-
经常被修改的字段
-
表中的数据很少时
什么情况下索引会失效?
-
使用左模糊匹配或者左右模糊匹配
-
对索引字段使用了函数、计算表达式、类型转换
-
在联合索引时,没有遵循“最左匹配”的原则
-
where子句进行条件查询时,若出现or关键字连接两个条件,且一个条件是索引字段,一个条件不是时会出现索引失效
有什么提高索引性能的方法?
-
使用前缀索引。前缀索引是指将字段的前几个字符作为索引,而不将整个字段作为索引。这样整个节点会消耗更小的空间,从而一个索引页中可以存储更多的索引项
-
使用覆盖索引。覆盖索引是指二级索引就能直接获取查询想要的字段,而不需要回表操作
-
使主键索引自增。主键值自增的话,在插入新数据时,只需要在主键索引B+树进行追加操作,而不需要重新移动其他节点
-
防止索引失效