Btree
从上图可以看出:
(1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的
(2)非叶子结点存储的是叶子结点的索引(稀疏索引),叶子结点存储的是关键字和数据
(3)非叶子结点不能存数据
(4)顺序存储,每一个叶子节点到根结点的距离是相同的
(5)根节点横向也有链指针
可以用Btree索引进行全关键字、关键字范围和关键字前缀查询。如果使用索引,必须保证按索引最左边前缀进行查询。由于Btree中节点是顺序存储的,可以对查询结果进行order by。
限制:
(1)查询必须从索引的最左边的列开始
(2)不能跳过某一索引列。
(3)存储引擎不能使用索引中范围条件右边的列。
例如,如果你的查询语句为WHERE last_name=”Smith” AND first_name LIKE ‘J%’ AND dob=’1976-12-23’,则该查询只会使用索引中的前两列,因为LIKE是范围查询。
Hash
简单地说,哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。
从上面的图来看,Btree索引和Hash索引的明显区别是:
(1)如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值;当然了,这个前提是,键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据;
(2)从示意图中也能看到,如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;
同理,哈希索引也没办法利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);
(3)哈希索引也不支持多列联合索引的最左匹配规则;
(4)Btree的关键字检索效率比较平均,不像Hash那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题。