MySQL索引类型 btree索引和hash索引的区别

本文对比了MySQL中BTree索引和Hash索引的特点与应用场景。Hash索引在精确匹配查询时表现出更高的效率,但不支持范围查询、排序及部分索引键查询。BTree索引虽然查询效率略低,但在灵活性上更具优势。

MySQL索引类型 btree索引和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 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

 

来源二

 

1. hash索引查找数据基本上能一次定位数据,当然有大量碰撞的话性能也会下降。而btree索引就得在节点上挨着查找了,很明显在数据精确查找方面hash索引的效率是要高于btree的;

2. 那么不精确查找呢,也很明显,因为hash算法是基于等值计算的,所以对于“like”等范围查找hash索引无效,不支持;

3. 对于btree支持的联合索引的最优前缀,hash也是无法支持的,联合索引中的字段要么全用要么全不用。提起最优前缀居然都泛起迷糊了,看来有时候放空得太厉害;

4. hash不支持索引排序,索引值和计算出来的hash值大小并不一定一致。

 

手册介绍地址:http://dev.mysql.com/doc/refman/5.6/en/create-index.html

内容由吠品原创/整理/转载,发布在http://www.cnblogs.com/osfipin/,欢迎评论。


MySQLBTree 索引Hash 索引在数据结构、适用场景、性能特点等方面存在显著差异。 ### 数据结构差异 BTree 索引基于 B+ 树结构,是一种平衡多路搜索树,能够支持范围查询、有序遍历以及模糊匹配等操作。B+ 树的每个节点可以包含多个键值子节点指针,适合磁盘存储,因为每次查询只需要访问少量的磁盘块[^1]。 Hash 索引则基于哈希表结构,仅适用于等值查询操作。哈希索引通过哈希函数将键值映射为存储位置,理论上可以在常数时间内完成查找,查询效率非常高[^1]。 ### 有序性与查询能力 BTree 索引是**有序**的,因此可以用于范围查询(如 `WHERE age BETWEEN 18 AND 30`)、模糊匹配(如 `LIKE 'T%'`)排序操作(如 `ORDER BY age`)。 Hash 索引是**无序**的,不支持范围查询、模糊匹配或排序操作,仅适用于等值比较(如 `WHERE name = 'Tom'`)[^1]。 ### 查询效率与更新代价 BTree 索引的查询时间复杂度为 **O(log n)**,虽然不如哈希索引快,但其性能稳定,适用于多种查询类型Hash 索引的查询时间复杂度为 **O(1)**,理论上效率更高,但在实际应用中可能因为哈希冲突而影响性能[^1]。此外,频繁更新可能导致哈希表重新哈希,带来额外开销[^1]。 ### 存储引擎支持 InnoDB 存储引擎默认使用 BTree 索引,适用于大多数事务性场景。 Memory 存储引擎默认使用 Hash 索引,但也可以手动配置为使用 BTree 索引,适用于临时表内存表的等值查询场景[^1]。 ### 联合索引支持 BTree 索引支持联合索引,并遵循最左前缀匹配原则,能够优化多列查询性能。 Hash 索引不支持联合索引,无法利用最左前缀原则进行优化[^1]。 ### 使用场景建议 - **Hash 索引**适用于数据量较小且查询模式为等值查找的场景,如 Memory 引擎中的临时表查询。 - **BTree 索引**适用于需要支持范围查询、排序、模糊匹配等复杂查询的场景,如 InnoDB 引擎中的事务处理。 ### 示例对比 以下是一些典型 SQL 查询场景: ```sql -- 等值查询 SELECT * FROM user WHERE name = 'Tom'; -- Hash 索引效率更高 ``` ```sql -- 模糊匹配 SELECT * FROM user WHERE name LIKE 'T%'; -- BTree 索引支持 ``` ```sql -- 范围查询 SELECT * FROM user WHERE age BETWEEN 18 AND 30; -- BTree 索引支持 ``` ```sql -- 排序 SELECT * FROM user ORDER BY age; -- BTree 索引支持 ``` ### 总结对比表 | 维度 | BTree 索引 | Hash 索引 | |----------------|------------------|------------------| | 是否有序 | ✅ 是 | ❌ 否 | | 支持范围查询 | ✅ 是 | ❌ 否 | | 支持模糊匹配 | ✅ 是 | ❌ 否 | | 支持排序 | ✅ 是 | ❌ 否 | | 查询性能 | 稳定 O(log n) | 理想 O(1) | | 存储引擎默认 | InnoDB、MyISAM | Memory(默认) |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值