索引结构
文章目录
- 索引结构
-
- 1. Hash
- 2. B-Tree
- 3. B+Tree
-
-
- 面试题
-
- 【MySQL数据库|MySQL高级篇之索引结构】MySQL 的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,主要包含以下几种 :
索引结构 描述 B+Tree索引 最常见的索引类型,大部分引擎都支持 B+ 树索引 Hash索引 底层数据结构是用哈希表实现的, 只有精确匹配索引列的查询才有效, 不支持范围查询 R-tree(空间索引) 空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少 Full-text(全文索引) 是一种通过建立倒排索引,快速匹配文档的方式 索引结构 InnoDB MyISAM Memory B+Tree索引 支持 支持 支持 Hash 索引 不支持 不支持 支持 R-Tree 索引 不支持 支持 不支持 Full-text 5.6版本之后支持 支持 不支持
- 如果没有特别指明,都是使用 B+Tree 结构组织的索引。
- 只有 Memory 存储引擎支持 Hash 索引。
- 只有 MyISAM 存储引擎支持 R-Tree 索引。
- Hash表,在 Java 中的 HashMap,TreeMap 就是 Hash 表结构,以键值对的方式存储数据。我们使用 Hash 表存储,表数据 Key 可以存储索引列,Value 可以存储行记录或者行磁盘地址。Hash 表在
等值查询
时效率很高,但是不支持范围快速查找
,范围查找时还是只能通过扫描全表方式。 - InnoDB: 具有自适应 hash 功能,hash索引是存储引擎根据 B+Tree 索引在指定条件下自动构建的
- 背景:
- 二叉树在大部分情况下都可以提高检索速度,但在
顺序插入
时,会形成一个链表,查询性能大幅度降低。数据量大的情况下,层级较深,检索速度慢。
- 红黑树可以很好的解决顺序插入的问题,不过在数据量大的情况下,也存在层级较深,检索速度慢的问题。
- 二叉树在大部分情况下都可以提高检索速度,但在
- 因为在 MySQL 的 InnoDB 存储引擎一次 IO 会读取的一页(默认一页16K)的数据量,而二叉树一次 IO 有效数据量只有16字节,空间利用率极低。为了最大化利用一次 IO 空间,一个简单的想法是在每个节点存储多个元素,在每个节点尽可能多的存储数据。每个节点可以存储1000个索引(16k/16=1000),这样就将二叉树改造成了多叉树,通过增加树的叉树,将树从高瘦变为矮胖。构建1百万条数据,树的高度只需要2层就可以(1000*1000=1百万),也就是说只需要2次磁盘 IO 就可以查询到数据。磁盘 IO 次数变少了,查询数据的效率也就提高了。
- 这种数据结构我们称为B树,B树是一种
多叉平衡查找树
,如下图主要特点:
- B树的节点中存储着多个元素,每个内节点有多个分叉。
- 节点中的元素包含键值和数据,节点中的键值从大到小排列。也就是说,在所有的节点都储存数据。
- 父节点当中的元素不会出现在子节点中。
- 所有的叶子结点都位于同一层,叶节点具有相同的深度,叶节点之间没有指针连接。
文章图片
- 缺点:
- B树不支持范围查询的快速查找。如果想要查找10和35之间的数据,查找到15之后,需要回到根节点重新遍历查找,需要从根节点进行多次遍历,查询效率有待提高。
- 如果 data 存储的是行记录,行的大小随着列数的增多,所占空间会变大。这时,一个页中可存储的数据量就会变少,树相应就会变高,磁盘IO次数就会变大。
- B+Tree,在 B+Tree 基础上进行了改造。B+Tree 和 B-Tree 最主要的区别在于
非叶子节点是否存储数据
的问题,即:
- B-Tree:非叶子节点和叶子节点都会存储数据。
- B+Tree:只有叶子节点才会存储数据,非叶子节点
只存储键值
。叶子节点形成一个单向链表
,非叶子节点仅仅起到索引数据的作用,具体的数据都是在叶子节点存放的 。
- MySQL 索引数据结构对经典的 B+Tree 进行了优化。在原 B+Tree 的基础上,增加一个指向相邻叶子节点的链表指针,即叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个
双向有序链表
。进一步提高区间访问的性能,利于排序。
文章图片
- MySQL 对 B+Tree 进行了优化之后,可以保证等值和范围查询的快速查找。
面试题
- 为什么 InnoDB 存储引擎选择使用 B+Tree 索引结构?(B+Tree 的优点?)
- 相对于二叉树,层级更少,搜索效率高。
- 对于 B-Tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针也跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低。
- 相对于 Hash 索引,B+Tree 支持范围匹配及排序操作。
推荐阅读
- MySQL|MySQL中tinyint(1)与tinyint(2)的区别
- MYSQL|【MYSQL】表的综合查询
- 面试|CentOS下安装及配置MySQL
- mysql|MySQL中的中文报错--保姆级解决方法
- java|springboot和springmvc的区别
- 面试|SQLAlchemy使用教程
- 瑞吉外卖|猿创征文|瑞吉外卖——移动端_笔记
- 瑞吉外卖|猿创征文|瑞吉外卖——移动端_订单明细
- 瑞吉外卖|猿创征文|瑞吉外卖——移动端_购物车