mysql B-tree索引与hash索引

一.mysql支持的索引类型

     mysql的索引是在存储引擎层实现的,即使同一种索引在不同的存储引擎上也可能底层实现不同。

    1.1 B-tree索引是我们最常见的索引。

(1)特点:

使用b+树结构存储数据。b+树结构特点:每一个节点都存储下一个节点的指针。这样可以方便叶子节点的遍历。每一个叶子节点到根节点的距离是相同的。并且所有叶子节点都是根据键值大小按顺序存放,并且节点直接通过指针来链接。B-tree在不同的存储引擎下实现是不同的,Myiasm是在叶子节点上是通过数据的物理位置来进行引用行的,innodb是通过主键来引用B-tree索引的行。

mysql B-tree索引与hash索引_第1张图片

我们可以发现B-tree的大小远远小于存储数据的大小,这样存储引擎就不需要全表扫描来获取数据,取而代之是从索引的根节点进行搜索。索引的根节点中存放了下层节点的指针,通过比较节点的值和要查找的值,可以得到合适的指针进入下一层节点。这些指针定义了值的上限与下限,存储引擎要找到对应的值可以确定索引所要查找的值是否存在,最终存储引擎通过B-tree索引找到符合要求的节点。叶子节点比较特别,指针指向被索引的数据而非其他的节点。

B-tree索引更适合范围查找。B-tree索引同一层节点根据键值大小按顺序存放。

         (2)在什么情况下使用B-tree索引

         全值匹配:和索引中的所有列来进行全值匹配。

匹配最左前缀的查询:联合索引只要第一列符合查询条件就会被用到。

匹配列前缀的查询:匹配某一列数据的前缀。

匹配范围查找:

精确匹配左前列并范围匹配另一列。

只访问索引的查询:覆盖索引。只访问索引而不查询数据行,这种查询数据非常高。

同时B-tree也支持排序。因为其存储按照键顺序存放。

(3)Btree索引的使用限制

所用索引所命中了表中大部分的数据时,mysql查询优化器认为全表扫描可能会性能个更好。

若不是按照索引列最左列开始查找,则无法使用索引。

使用索引时不能跳过索引中的列。

Not in 和 <>操作无法使用索引。

如果查询中有某个列的范围查询,则其右边所有列都无法使用索引。

2.Hash索引定义:

innodb根据b-tree索引的所用情况自己建立的,自适应hash索引。
(1)hash索引是基于hash表实现的,只有查询条件精确匹配,hash索引中的所有列时才能使用Hash索引。模糊查询,范围查询不支持。
(2)对于hash索引中的所有列,存储引擎都会为每一行计算一个Hash码,hash索引中存储的就是hash码。它的存储很紧凑,查询速度快。
2.hash索引限制
(1)hash索引必须进行两次查询,hash索引存储:键值,hash码,行指针。
使用Hash必须先找到行指针,然后再去行读取。
(2)hash索引无法排序hash索引按照hash存储而非键值存储,所以不能像btree索引那样查询结果进行排序。
(3)hash索引不支持范围查找,部分索引查找
(4)hash冲突。不同行可以计算出相同的hash值。hash码通常都比较小。为了提高效率。一旦产生大量的hash冲突,就会影响hash的查找。索引hash索引不适合存储在重复性多的列。
3.为啥要使用索引?
使用索引可以快速定位要访问的数据,大大减少了存储引擎需要扫描的数量。
btree索引是按照顺序存储,所以我们可以进行排序。避免使用磁盘临时表来进行排序。减少io消耗。
索引查找可以把随机IO改为顺序IO。数据行的存储通常都是随机分布的。更加充分发挥磁盘IO性能。
只有索引带来的好处大于其坏处,那么才是有效的。
索引会增加操作的成本。增删改操作都需要维护索引。
过多索引也会增加查询优化器的选择时间。mysql查询优化器会根据索引的统计信息和查询条件为查询选择合适的索引。若可选择的索引越多,mysql查询统计信息生成执行计划的时间。

你可能感兴趣的:(数据库)