3.3 常见的索引概念
索引按照物理实现方式,索引可以分为 2 种:聚簇和非聚簇索引
1、聚簇索引
5、索引的代价
-
空间上的代价
每建立一个索引都要为它建立一棵B+树,每一棵B+树的每一个节点都是一个数据页,一个页默认会占用 16KB 的存储空间,一棵很大的B+树由许多数据页组成,那就是很大的一片存储空间。 -
时间上的代价
每次对表中的数据进行 增、删、改 操作时,都需要去修改各个B+树索引
6、MySQL数据结构选择的合理性
从MySQL的角度讲,不得不考虑的一个现实问题就是磁盘IO,如果我们能让索引的数据结构尽量减少硬盘的I/O操作,所消耗的时间也就越小。可以说:磁盘的I/O次数对索引的使用效率至关重要
查找都是索引操作,一般来说索引非常大,尤其是关系型数据库,当数据量比较大的时候,索引的大小有可能几个G甚至更多,为了减少索引在内存中的占用,索引都是存储在外部磁盘上的。当我们利用索引查询的时候,不可能将整个索引全部加载到内存,只能逐一加载,那么MySQL衡量查询效率的标准就是磁盘的IO次数
6.1 全表遍历
6.2 Hash结构
上图中哈希函数h有可能将两个不同的关键字映射到相同的位置,这叫做 碰撞 ,在数据库中一般采用 链接法来解决。在链接法中,将散列到同一槽位的元素放在一个链表中,如下图所示:
Hash结构效率高,那为什么索引结构要设计成树型呢?
Hash索引的适用性:
InnoDB本身你不支持Hash索引,但是提供自适应的Hash索引。采用自适应 Hash 索引目的是方便根据 SQL 的查询条件加速定位到叶子节点,特别是当 B+ 树比较深的时候,通过自适应 Hash 索引可以明显提高数据的检索效率。
6.3 二叉搜索树
如果我们利用二叉树作为索引结构,那么磁盘的IO次数和索引树的高度是相关的。
为了提高查询效率,就需要 减少磁盘IO数 。为了减少磁盘IO的次数,就需要尽量 降低树的高度 ,需要把原来“瘦高”的树结构变的“矮胖”,树的每层的分叉越多越好。
6.4 AVL树 (平衡二叉树)
左右子树的高度差不能超过 1
6.5 B-Tree
B树的英文是Balance Tree,也就是多路平衡查找树,它的高度远小于平衡二叉树的高度
B 树的结构如下图所示:
一个 M 阶的 B 树(M>2)有以下的特性:
- 根节点的儿子数的范围是 [2,M]。
- 每个中间节点包含 k-1 个关键字和 k 个孩子,孩子的数量 = 关键字的数量 +1,k 的取值范围为[ceil(M/2), M]。
- 叶子节点包括 k-1 个关键字(叶子节点没有孩子),k 的取值范围为 [ceil(M/2), M]。
- 假设中间节点节点的关键字为:Key[1], Key[2], …, Key[k-1],且关键字按照升序排序,即 Key[i]<Key[i+1]。此时 k-1 个关键字相当于划分了 k 个范围,也就是对应着 k 个指针,即为:P[1], P[2], …,P[k],其中 P[1] 指向关键字小于 Key[1] 的子树,P[i] 指向关键字属于 (Key[i-1], Key[i]) 的子树,P[k]指向关键字大于 Key[k-1] 的子树。
- 所有叶子节点位于同一层。
6.6 B+Tree
B+ 树和 B 树的差异: