问七:谈谈数据库索引?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_18657175/article/details/89465219

为什么要使用索引?

避免全表扫描去查找数据,提升检索效率


什么样的信息能够成为索引?

主键、唯一键等只要是能让数据具备一定区分性的字段都能成为索引


数据库索引有哪些?区别?作用?


索引的数据结构:

生成索引,建立二叉查找树进行二分查找

生成索引,建立B Tree结构进行查找

生成索引,建立B+ Tree树结构进行查找(主流)

生成索引,建立Hash、BitMap结构进行查找(MySQL不支持BitMap,基于InnoDB、MyISAM的MySQL不显式支持hashMermory支持hash

索引的数据结构

一、二叉查找树

使用二叉查找树(左孩子比父结点小,右孩子比父结点大,时间复杂度O(logn),但是最坏情况下,就是所有的子结点都比父结点大,时间复杂度就是O(n))

可以利用树旋转的特性来保持其为一颗平衡二叉树(左结点和右结点之间的高度差不大于1),这样就可以维持其时间复杂度为O(logn)

但是即使使用上面的方案,其速度瓶颈依旧会存在,存在的地方就是IO

因为我们假设每个数据块都存储在磁盘中,每次寻找一个数据块都会发生一次IO检索的深度每增加1,就会发生一次IO。正是由于平衡二叉查找树和红黑树只能有两个孩子结点,所以如果数据一多,层就会很深,发生IO的次数也会非常的多,因此不使用平衡二叉查找树和红黑树。

如何既降低查询的时间复杂度又降低IO的次数,就是让树从“瘦高”转化为“矮胖”,每个结点能够存储的数据多一些,同时降低树的高度,减少磁盘IO次数,就引入B树了


二、B树

首先看的定义:

1.所有叶节点具有相同的深度,也就是说B-Tree是平衡的

2.一个节点中的 key从左到右非递减排列

3.如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不为null,则该指针指向节点的所有key大于等于keyi且小于等于 keyi+1。

查找算法:首先在根节点进行二分查找,如果找到则返回对应节点的data,否则在相应区间的指针指向的节点递归进行查找。由于插入删除新的数据记录会破坏B-Tree的性质,因此在插入删除时,需要对树进行一个分裂、合并、旋转等操作以保持B-Tree性质。


三、B+树

与 B-Tree 相比,B+Tree有以下不同点:

1.每个节点的指针上限为2d而不是2d+1(d为节点的出度)

2.非叶子结点不存储 data,仅用来当索引

【这一步的优点就是将所有的数据都存在了叶子结点,其他用来当索引,可以减少查找时的IO,非叶子结点能够存储更多的关键字,树就更矮】

3.叶子节点不存储指针

4.所有的叶子结点均有一个链指针指向下一个叶子结点【一般在数据库系统或文件系统中使用的B+Tree结构都在经典 B+Tree 基础上进行了优化,在叶子节点增加了顺序访问指针,做这个优化的目的方便做范围统计,不用回到它的父节点进行搜索】

查找算法:进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。

和B树相比的优点

(一)更少的检索次数

平衡树检索数据的时间复杂度等于树高h,而树高大致为O(h)=O(logdN),其中d为每个节点的出度。

B+Tree相比于B-Tree 更适合外存索引,因为 B+Tree 非叶子节点去掉了data域,因此可以拥有更大的出度,检索效率会更高,由此可见BTree不会用在mysql中实现,mysql是基于缓存和外存实现的

(二)充分利用计算机的预读特性

为了减少磁盘 I/O,磁盘往往不是严格按需读取,而是每次都会预读局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。预读过程中,磁盘进行顺序读取,顺序读取不需要进行磁盘寻道,并且只需要很短的旋转时间,因此速度会非常快。操作系统一般将内存和磁盘分割成固定大小的块(一般按页来读入,一个页大小一般为4K),内存与磁盘以页为单位交换数据数据库系统将索引的一个节点的大小设置为页的大小,使得一次 I/O 就能完全载入一个节点,并且可以利用预读特性,相邻的节点也能够被预先载入。


四、Hash

其中Hash有很多缺点:仅仅能满足“=”,“IN”不能使用范围查询

1.无法排序数据(因为Hash索引中存放的是经过hash运算后的值,其大小关系也不一定和原数据相同)

2.不能利用部分索引键查询(就是查询条件里只写部分条件)

3.不能避免表扫描

4.遇到大量Hash值相等的情况时,性能并不一定会比B树索引高


五、BitMap

但是BitMap索引是个神器,支持该索引的数据库较少,比如oracle。

查询速度非常快,因为如果字段值只有固定几个,就可以用每个位的01来表示,每个块中就可以存很多关键字了。

锁的力度非常的大,当尝试添加或者删除一个数据的时候,与它位于位图的数据操作都有可能被锁住,因此不适合高并发的系统,适合于统计较多的系统


索引的优点:

1.减少了服务器需要扫描的数据行数

2.帮助服务器避免进行排序和创建临时表(B+Tree 索引是有序的,可以用来做 ORDER BY 和 GROUP BY 操作)

3.将随机 I/O 变为顺序 I/O(B+Tree 索引是有序的,也就将相邻的数据都存储在一起)


索引是建立得越多越好吗?

数据量小的表不需要建立索引,建立索引会增加额外的索引开销

数据变更需要维护索引,因此更多的索引意味着更多的维护成本

更多的索引意味着也需要更多的空间

猜你喜欢

转载自blog.csdn.net/qq_18657175/article/details/89465219
今日推荐