Hash索引与B-Tree索引

Hash索引

Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。
      可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢?任何事物都是有两面性的,Hash 索引也一样,虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。

(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。
     由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
(2)Hash 索引无法被用来避免数据的排序操作。
     由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
(3)Hash 索引不能利用部分索引键查询。
     对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
(4)Hash 索引在任何时候都不能避免表扫描。
     前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
     对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

B-Tree索引

B-Tree 索引是 MySQL 数据库中使用最为频繁的索引类型,除了 Archive 存储引擎之外的其他所有的存储引擎都支持 B-Tree 索引。不仅仅在 MySQL 中是如此,实际上在其他的很多数据库管理系统中B-Tree 索引也同样是作为最主要的索引类型,这主要是因为 B-Tree 索引的存储结构在数据库的数据检索中有非常优异的表现。
一般来说, MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的结构来存储的,也就是所有实际需要的数据都存放于 Tree 的 Leaf Node ,而且到任何一个 Leaf Node 的最短路径的长度都是完全相同的,所以我们大家都称之为 B-Tree 索引当然,可能各种数据库(或 MySQL 的各种存储引擎)在存放自己的 B-Tree 索引的时候会对存储结构稍作改造。如 Innodb 存储引擎的 B-Tree 索引实际使用的存储结构实际上是 B+Tree ,也就是在 B-Tree 数据结构的基础上做了很小的改造,在每一个Leaf Node 上面出了存放索引键的相关信息之外,还存储了指向与该 Leaf Node 相邻的后一个 LeafNode 的指针信息,这主要是为了加快检索多个相邻 Leaf Node 的效率考虑。
在 Innodb 存储引擎中,存在两种不同形式的索引,一种是 Cluster 形式的主键索引( Primary Key ),另外一种则是和其他存储引擎(如 MyISAM 存储引擎)存放形式基本相同的普通 B-Tree 索引,这种索引在 Innodb 存储引擎中被称为 Secondary Index 。下面我们通过图示来针对这两种索引的存放形式做一个比较。

图示中左边为 Clustered 形式存放的 Primary Key ,右侧则为普通的 B-Tree 索引。两种 Root Node 和 Branch Nodes 方面都还是完全一样的。而 Leaf Nodes 就出现差异了。在 Prim中, Leaf Nodes 存放的是表的实际数据,不仅仅包括主键字段的数据,还包括其他字段的数据据以主键值有序的排列。而 Secondary Index 则和其他普通的 B-Tree 索引没有太大的差异,Leaf Nodes 出了存放索引键 的相关信息外,还存放了 Innodb 的主键值。

所以,在 Innodb 中如果通过主键来访问数据效率是非常高的,而如果是通过 Secondary Index 来访问数据的话, Innodb 首先通过 Secondary Index 的相关信息,通过相应的索引键检索到 Leaf Node之后,需要再通过 Leaf Node 中存放的主键值再通过主键索引来获取相应的数据行。MyISAM 存储引擎的主键索引和非主键索引差别很小,只不过是主键索引的索引键是一个唯一且非空 的键而已。而且 MyISAM 存储引擎的索引和 Innodb 的 Secondary Index 的存储结构也基本相同,主要的区别只是 MyISAM 存储引擎在 Leaf Nodes 上面出了存放索引键信息之外,再存放能直接定位到 MyISAM 数据文件中相应的数据行的信息(如 Row Number ),但并不会存放主键的键值信息。

我是天王盖地虎的分割线

参考:http://blog.sina.com.cn/s/blog_6776884e0100pko1.html

时间: 2024-10-25 07:19:53

Hash索引与B-Tree索引的相关文章

MySQL/MariaDB的 B+ TREE索引

在我们CentOS 7+版本之后的自带镜像中的MariaDB使用的默认引擎是InnoDB引擎: InnoDB引擎自带的特点: 1.InnoDB存储引擎将数据存储于"表空间"中: 2.支持事务 3.精细锁粒度支持:表级锁.页级锁.行级锁.间隙锁: 4.支持聚集索引,主键索引以及辅助索引,自适应的Hash索引: 简要介绍一下事务: 所谓事务:就是一组原子性的SQL查询或者是一个或多个SQL语句组成的独立的操作单元: 一个最简单易懂的事务例子: A 借 B 100块钱,A 得到100,则相应

索引的分类--B-Tree索引和Hash索引

索引是存储引擎用来快速查找记录的一种数据结构,按照实现的方式有不同的种类,想B-Tree索引,hash索引,空间数据索引和全文索引等.下面主要说一下B-Tree索引和Hash索引.人们在谈论索引的时候如果没有特别说明,一般指的是B-Tree索引.B-Tree索引是使用B-Tree数据结构来存储索引的.B-Tree通常意味着所有的值是按照顺序存储的.B-Tree树有如下几个特征:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点,则至少有两棵子树:⑶除根结点之外的所有非终端结点至少有[m/2]

mysql B+Tree索引

原文地址:http://blog.codinglabs.org/articles/theory-of-mysql-index.html 数据结构及算法基础 索引的本质 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 我们知道,数据库查询是数据库的最主要功能之一.我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化.最基本的查询算法当然是顺序查找(linear searc

B+tree索引

B+Tree索引 如上图,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1.P2.P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块.真实的数据存在于叶子节点即3.5.9.10.13.15.28.29.36.60.75.79.90.99, 非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17.35并不真实存在于数据表中. B+索引在InnoDB和MyI

复合B*tree索引branch block内是否包含非先导列键值?

好久不碰数据库底层细节的东西,前几天,一个小家伙跑来找我,非要说复合b*tree index branch block中只包含先导列键值信息,并不包含非先导列键值信息,而且还dump了branch block,用以证明他的说法,从常理和SQL的语句执行信息就可以知道,他的说法是有问题的,但如何证明这一点呢?为了证明这点,也麻烦一次,玩玩多年不碰的dump.下面是他证明自己观点的两个dump结果(一个为单键索引,另一个是复合索引): 下面是本人的测试过程和结果: create table t1(c

B tree索引学习总结

b tree索引 索引的结构: 1.创建一个测试表 create table it (x number ,y varchar2(100)); 2.插入一万行数据 begin for i in 1..100000 loop insert into it values(i,rpad(i,100,'*')); end loop; end; / 3.创建索引在x列上 create index idx_it on it(x); 4.收集表信息 SQL> exec dbms_stats.gather_tab

【连载】关系型数据库是如何工作的?(5) - B+Tree索引

虽然上一章节介绍的二叉搜索树在查询指定值时表现很好,但是当查询两个值之间的多个节点时,就会遇到很大的问题.因为需要遍历整个树的节点,并检查每个节点是否在指定的区间内.而且遍历整颗树是随机磁盘IO(译者注:随机IO会导致频繁的磁头换道,所以相比顺序IO来说非常耗时),所以我们需要找到一种更有效做范围查询的方法.为了解决这个难题,现代数据库修正了之前介绍的二叉搜索树,我们称修正后的数据结构为B+Tree: 只有叶子节点(树最底层的节点,图中橘黄色的节点)存储信息,即:行在表中精确的位置,也就是row

java面试题:你了解mysql的B+TREE索引吗?

什么是索引? 索引是为了加速对表中数据行的检索而创建的一种分散储存的数据结构. 工作原理: 通过我们建立的索引,可以通过命中后的磁盘地址快速的找到我们需要的表数据,比起全表扫描去查询数据,可以大大的提升查找效率. 在关系型数据库中,索引是硬盘级索引. 常见的数据结构 1)二叉树 二叉树相信大家都非常熟悉,以一个节点为根节点,比该节点小的值走左边,大的值走右边.搜索数据时,只要通过它的数据链接就可找到相应的数据.右边为一个节点里的具体组成部分. 缺点:二叉树有个极其致命的缺点,当插入数据为顺序递增

Mysql B-Tree和B+Tree索引

Mysql B-Tree和B+树索引 Mysql加快数据查找使用B-Tree数据结构存储索引数据,InnoDB存储引擎实际使用B+Tree.下面首先介绍下B-Tree和B+Tree的区别: 一.B树和B+树索引(手绘图简要说明) 1.B-Tree索引: 2.B+Tree索引: 3.B-Tree 和B+Tree索引查找原理: 非叶子节点存储索引关键字,叶子节点指针指向的是被索引的数据.节点槽中存放了指向子节点的指针(可以理解为两个关键字之间),存储引擎根据这些指针向下层查找.通过比较节点页的值和要

Mysql索引——B-Tree/B+Tree架构

在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择使用B+树! 学过数据结构的一般对最基础的树都有所认识,因此我们就从与我们主题更为相近的二叉查找树开始. 一.二叉查找树 (1)二叉树简介: 二叉查找树也称为有序二叉查找树,满足二叉查找树的一般性质,是指一棵空树具有如下性质: 1.任意节点左子树不为空,则左子树的值均小于根节点的值: 2.任意节点右子