数据库-索引

1 索引概念&索引优缺点

索引就是一种用于快速查询和检索数据的数据结构,常见索引:B树,B+树,Hash

索引的作用就相当于目录,如查字典时,如果没有目录,就只能一页一页去找,速度很慢
如果有目录,就可以通过目录查找字的位置,然后直接翻到那一页

索引的优缺点:

优点: 
1,使用索引可以大大加快数据的检索速度,这也是创建索引最主要的原因

2,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性


缺点:
1,创建和维护索引需要耗费很多时间,当对表中的数据增删改时
如果对应数据有索引,索引也需要修改,会降低SQL的执行效率

2,索引需要物理文件存储,需要占用一定空间

大多数情况下,使用索引是一定比全表扫描要快的
但是如果数据库的数据量不大,使用索引也不一定能带来很大提升

2 索引底层数据结构

2.1 Hash表

Hash表是键值对的集合,通过key可以快速取出对应的值,因此哈希表可以快速检索数据,接近O(1)

为何能通过key快速取到value,原因在于哈希算法,也称散列算法
通过hash算法,可以通过key快速找到value对应的index,找到index就能找到对应value

hash = hashfunc(key)
index = hash % array_size

在这里插入图片描述
但是Hash表存在Hash冲突的问题,也就是说多个不同的key经过hash得到的index相同,为了解决Hash冲突,常用的解决办法是开地址法/拉链法,拉链法就是将Hash冲突的数据存储到链表中,如JDK1.8之前的HashMap就是通过拉链法来解决哈希冲突的,但在1.8之后,为了减少由于链表过长导致搜索时间过长而引进了红黑树
在这里插入图片描述
为了减少Hash冲突,一个好的Hash函数应该“均匀地”将数据分布在整个Hash集合中

既然Hash表查找效率这么快,为什么MySQL不使用Hash表作为索引?

1Hash表存在Hash冲突

2Hash索引不支持顺序和范围查找,这是它最大的缺点
假如想对表中的数据进行排序或者进行范围查询,那Hash索引就不能用了
如下面的情况:
SELECT * FROM tb1 WHERE id < 500;
这种范围查询中,直接遍历id<500的记录即可
而Hash表需要根据hash算法来定位,需要把1-499的所有数据每个都进行一次hash计算才能找到对应记录

2.2 B树&B+树

B树也称B-树,全称为多路平衡查找树,B+树是B树的一种变体,B是Balance(平衡)的意思
目前大部分数据库及文件系统都采用B树或B+树作为索引结构

2.2.1 B树

B树类似于普通的平衡二叉树(AVL),不同的是B树允许每个节点有更多的子结点
在这里插入图片描述

B树的特点:
1,所有键值分布在整棵树中(key和具体的data都存放在每个节点中)

2,任何一个关键字只会出现在一个节点中

3,搜索有可能会在非叶子节点结束(最好情况O(1)就能找到数据)

4,在关键字全集内做一次查找,性能逼近二分查找

2.2.2 B+树

B+树是B树的变体,也是一种多路搜索树
在这里插入图片描述

B+树是B树的变体,也是一种多路搜索树,它与B树不同点在于:

1,所有数据存储在叶子节点,其它内节点只存放key

2,为所有叶子节点增加了一个链指针

2.2.3 B树和B+树的区别

1B树的所有节点既存放key也存放data
而B+树只有叶子节点存放key和data,其它内节点只存放key

2B树的叶子节点都是独立的,B+树的叶子节点有一条引用链指向与它相邻的叶子节点

3B树的检索过程相当于对范围内的每个节点的关键字做二分查找,可能还没查到叶子节点,查找就结束了
而B+树的检索很稳定,任何查找都是从根到叶子节点的过程,叶子节点检索的顺序很明显

在MySQL中,MyISAM引擎和InnoDB引擎都是使用B+树作为索引结构,但是二者实现的方式不同:

1,在MyISAM中,B+树叶子节点的data域存储的是数据记录的地址
在检索索引时,首先按照B+树的搜索算法搜索索引,如果指定key存在
则取出对应data域的值,然后以data域的值作为地址再去读取相应的数据记录,称为"非聚簇索引"

2InnoDB中,数据文件本身就是索引文件,叶子节点的data域中保存的就是完整的数据记录
叶子节点的key就是表中对应记录的主键,称为"聚簇索引"
而其余的索引都作为辅助索引,辅助索引的data域存储相应记录主键的值

在根据主索引搜索时,直接找到key所在的节点即可取出数据
在根据辅助索引查找时,先需要取出主键的值,再走一遍主索引
因此在设计表中,不建议使用过长的字段作为主键,也不建议使用非单调的字段作为主键

3 索引类型

3.1 主键索引

数据库中表的主键使用的就是主键索引

一张表只能有一个主键,且主键不能为null,不可重复

在InnoDB的表中,当没有显示指定表的主键时,InnoDB会自动检查表中是否有唯一索引的字段
如果有,则选择该字段为默认的主键,否则InnoDB会自动创建一个6Byte的自增主键

3.2 二级索引(辅助索引)

二级索引又称辅助索引,是因为二级索引的叶子节点存储的数据是主键,也就是说通过二级索引可以定位主键的位置

唯一索引,普通索引,前缀索引都属于二级索引
在这里插入图片描述

4 聚簇索引与非聚簇索引

4.1 聚簇索引

聚簇索引即索引结构和数据一起存放的索引,主键索引属于聚簇索引

对于InnoDB引擎表来说,该表的索引(B+)的每个非叶子节点存储索引,叶子节点存储索引和索引对应的数据

聚簇索引的优缺点:

优点: 聚簇索引的查询速度非常快,因为整个B+树本身就是一颗多叉平衡树
叶子节点也都是有序的,定位到索引的节点,就相当于定位到了数据

缺点:
1,依赖于有序的数据: 因为B+树是多路平衡树,如果索引的数据不是有序的,那么就需要在插入时排序
如果数据是整型还好,否则类似于字符串这种数据,插入或删除的速度肯定比较慢

2,更新代价大: 如果聚簇索引的数据被修改,那么对应的索引也要被修改
而且聚簇索引的叶子节点还存放着数据,修改开销较大,对于主键索引来说,主键一般都是不可被修改的

4.2 非聚簇索引

非聚簇索引即索引结构和数据分开存储的索引

二级索引属于非聚簇索引
二级索引的叶子节点存放的就是主键,根据主键再回表查询数据

非聚簇索引的优缺点:

优点:
1,更新代价要小于聚簇索引

缺点:
1,依赖于有序的数据
2,可能会回表查询,当查到索引对应的主键时,根据主键再去表中查找

5 创建/使用索引的建议

5.1 创建索引的建议

1,选择合适的字段创建索引
不为null的字段,被频繁查询的字段,频繁用于连接的字段

2,尽量避免使用频繁更新的字段作为索引
维护索引需要成本,经常被修改的字段作为索引需要额外的开销

3,尽可能考虑建立联合索引而不是单列索引
可以理解为每个索引都是一颗B+树,太多的索引会占更多的空间
如果是联合索引,多个字段作为索引,会节约空间

4,尽量避免冗余索引
如(name,city)(name) 能够命中前者,就一定能命中后者
应该扩展索引,而不是创建新的索引

5.2 使用索引的一些建立

1,对于中大型表建立索引都是非常有效的
但对于特大型表维护开销会很大,不适合建索引

2,可以删除长期未使用的索引,不用的索引存在会造成不必要的性能损耗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值