索引!可谓是重中之重。面试可谓是必问内容,当然了,平时开发对于SQL的优化也是很重要的
而当实践SQL优化不能盲目的操作,理论是支撑实践的基础
索引的意义
索引的本质就是一种排好序的数据结构。这个肯定都明白,自然而言就联想到字典中的目录
在详细讲解下面的索引数据前补充一句:
通过不断缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序事件,也就是说,有了这种索引机制,总是用同一种方式来锁定数据
索引分类
1.普通索引 index:加速查找
2.唯一索引
主键索引:primary key:加速查找+约束(不为空且唯一)
唯一索引:unique:加速查找+约束(唯一)
3.联合索引
primary key(id,name):联合主键索引
unique(id,name):联合唯一索引
index(id,name):联合普通索引
4.全文索引 fulltext:用于搜索很长的一篇文章的时候,效果最好
5.空间索引 spatial:了解就好
索引数据结构分类
在数据库中,索引数据结构是很多分类的,而你印象最深刻的是不是就B+树索引呢?那是因为平时我们使用的基本都是MySQL,而根据存储引擎的不同,有些索引是不支持,只有heap、Memory引擎支持哈希索引,InnoDB引擎自适应哈希索引,下面我就来逐条讲解
Step1:Hash索引
Hash索引是比较常见的一种,单条查询效率很高,时间复杂度为1
但是!Hash索引不是最常用的数据库索引类型,尤其是我们常用Innodb引擎就不支持Hash索引
原因:Hash索引适合精确查找,但是范围查找不适合
因为存储引擎会为每一行数据计算一个hash码,hash码都比较小,并且不同键值行的hash码通常是不一样的,hash索引存储的就是hash码,hash码之间没有规律,且hash操作并不能保证顺序性,所以查找出值相近的两个数据,Hash值相差很远,被分到不同的桶中。这就是为什么hash索引只能进行全职匹配的查询,因为只有这样,hash码才能够匹配到数据
那什么情况使用哈希索引呢?
select … from user where user_id = ? 这种等查询非常适合hash索引
因为只需要经过一次算法即可找到相应的键值;前提是键值都是唯一的。如果键值不唯一就需要先找到该键值所在位置,然后再根据链表往后扫描,直到找到相应的数据
Step2:二叉树
常见的索引数据结构是树结构,先来详解最经典也是最开始的二叉树
二叉树特点:
- 二叉树的时间复杂度为O(n)
- 一个节点只能有两个子节点。不能超过2
- 左子节点小于本节点,右子节点大于本节点
但是在极端情况下可能出现链化的情况,既节点一直在某一边增加,如下图
二叉树中,有一种特殊的结构>>>平衡二叉树 平衡二叉树特点
- 根节点会随着数据的改变而变更
- 数据量越多,遍历次数越多,IO次数就越多,就越慢(磁盘的IO由树高决定)
Step3:B树(二三树)
了解二叉树之后,我们可以进一步详解什么是B树了,大概的样子如下图
从B树的结构图中可以看到每个节点中不仅包含数据的key值,还有data值
而每页的存储空间是有限的,如果data比较大,会导致每个节点的key存储比较少,当数据量比较