导读

在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议。

二者区别

备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTREE,例如像下面这样的写法:

CREATE TABLE t(
aid int unsigned not null auto_increment,
userid int unsigned not null default 0,
username varchar(20) not null default ‘’,
detail varchar(255) not null default ‘’,
primary key(aid),
unique key(uid) USING BTREE,
key (username(12)) USING BTREE — 此处 uname 列只创建了最左12个字符长度的部分索引
)engine=InnoDB;

一个经典的B+树索引数据结构见下图:

(图片源自网络)

B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接。

在B+树上的常规检索,从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动,而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高。

因此,B+树索引被广泛应用于数据库、文件系统等场景。顺便说一下,xfs文件系统比ext3/ext4效率高很多的原因之一就是,它的文件及目录索引结构全部采用B+树索引,而ext3/ext4的文件目录结构则采用Linked list, hashed B-tree、Extents/Bitmap等索引数据结构,因此在高I/O压力下,其IOPS能力不如xfs。

详细可参见:

https://en.wikipedia.org/wiki/Ext4
https://en.wikipedia.org/wiki/XFS

哈希索引的示意图则是这样的:

(图片源自网络)

简单地说,哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。

从上面的图来看,B+树索引和哈希索引的明显区别是:

  • 如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值;当然了,这个前提是,键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据;

  • 从示意图中也能看到,如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;

  • 同理,哈希索引也没办法利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);

  • 哈希索引也不支持多列联合索引的最左匹配规则

  • B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题

后记

在MySQL中,只有HEAP/MEMORY引擎表才能显式支持哈希索引(NDB也支持,但这个不常用),InnoDB引擎的自适应哈希索引(adaptive hash index)不在此列,因为这不是创建索引时可指定的。

还需要注意到:HEAP/MEMORY引擎表在mysql实例重启后,数据会丢失。

通常,B+树索引结构适用于绝大多数场景,像下面这种场景用哈希索引才更有优势:

在HEAP表中,如果存储的数据重复度很低(也就是说基数很大),对该列数据以等值查询为主,没有范围查询、没有排序的时候,特别适合采用哈希索引

例如这种SQL:
SELECT … FROM t WHERE C1 = ?; — 仅等值查询

在大多数场景下,都会有范围查询、排序、分组等查询特征,用B+树索引就可以了。

2016年9.12日 京东二面的问题。

MySQL B+树索引和哈希索引的区别(转 JD二面)的更多相关文章

  1. MySQL B+树索引和哈希索引的区别

      导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BT ...

  2. B+树索引和哈希索引的区别[转]

    导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTRE ...

  3. mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)

    没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...

  4. B+树索引和哈希索引的区别——我在想全文搜索引擎为啥不用hash索引而非得使用B+呢?

    哈希文件也称为散列文件,是利用哈希存储方式组织的文件,亦称为直接存取文件.它类似于哈希表,即根据文件中关键字的特点,设计一个哈希函数和处理冲突的方法,将记录哈希到存储设备上. 在哈希文件中,是使用一个 ...

  5. mysql索引之哈希索引

    哈希算法 哈希算法时间复杂度为O(1),且不只存在于索引中,每个数据库应用中都存在该数据结构. 哈希表 哈希表也为散列表,又直接寻址改进而来.在哈希的方式下,一个元素k处于h(k)中,即利用哈希函数h ...

  6. B+树索引和哈希索引的明显区别是:

    如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值:当然了,这个前提是,键值都是唯一的.如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到 ...

  7. 通俗易懂理解 MySQL B+树、数据存储、索引等知识

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485630&idx=1&sn=681c9c0d ...

  8. mysql索引是什么?索引结构和使用详解

    索引是什么 mysql索引: 是一种帮助mysql高效的获取数据的数据结构,这些数据结构以某种方式引用数据,这种结构就是索引.可简单理解为排好序的快速查找数据结构.如果要查“mysql”这个单词,我们 ...

  9. MySQL索引(一)索引基础

    索引是数据库系统里面最重要的概念之一.一句话简单来说,索引的出现其实是为了提高数据查询的效率,就像书的目录一样. 常见模型 索引的出现是为了提高查询效率,但是实现索引的方式却有很多种,这里就介绍三种常 ...

随机推荐

  1. 代码 | 自适应大邻域搜索系列之(3) - Destroy和Repair方法代码实现解析

    前言 上一篇文章中我们具体解剖了ALNS类的具体代码实现过程,不过也留下了很多大坑.接下来的文章基本都是"填坑"了,把各个模块一一展现解析给大家.不过碍于文章篇幅等原因呢,也不会每 ...

  2. 题目1006:ZOJ问题(字符串处理)

    问题来源 http://ac.jobdu.com/problem.php?pid=1006 问题描述 输入一个只包含'z','o','j'三种字符的字符串,判断是否符合要求. 问题分析 分析AC的三个 ...

  3. jenkins发送测试报告邮件

     1.安装插件 Email Extension Plugin 2.设置Extended E-mail Notification a."系统管理"--“系统设置”.配置Extende ...

  4. JSP中使用JSTL表达式

    最近写web项目,为了使JSP代码美观好维护,决定采用EL&JSTL表达式.    EL表达式直接就可以用,但是JSTL表达式是属于apache的一个开源库,这个用起来就需要倒入一些jar包之 ...

  5. vue-cli3 chainWebpack配置,去除打包后文件的预加载prefetch/preload(已解决)

    //细节配置修改 chainWebpack: config => { console.log(config,'chainWebpack') // 移除 prefetch 插件 config.pl ...

  6. 基于iTop4412的FM收音机系统设计(二)

    说明:第一版架构为:APP+JNI(NDK)+Driver(linux),优点是开发简单,周期短,也作为自己的毕业设计 现在更新第二版,FM服务完全植入Android系统中,成为系统服务,架构为:AP ...

  7. c# SocketAsyncEventArgs类的使用 IOCP服务器

    要编写高性能的Socket服务器,为每个接收的Socket分配独立的处理线程的做法是不可取的,当连接数量很庞大时,服务器根本无法应付.要响应庞大的连接数量,需要使用IOCP(完成端口)来撤换并处理响应 ...

  8. Linux 下使用yum 命令安装MySQL

    Linux下使用yum安装MySQL,以及启动.登录和远程访问MySQL数据库. 1.yum安装mysql 1. 查看有没有安装包:   yum list mysql*    #移除已经安装的mysq ...

  9. 推荐几个好用的maven仓库镜像站

    1.阿里云的镜像站(速度很快) <mirror> <id>nexus-aliyun</id> <name>Nexus aliyun</name&g ...

  10. Modular Rails: The complete Guide to Modular Rails Applications 笔记

    fix SamuraiCRM/engines/core/test/dummy/config/routes 修改如下 Rails.application.routes.draw do mount Sam ...