「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」
创建高性能索引知识-思维导图
学完mysql需要知道以下几个问题:
- 为什么要有mysql索引
- mysql索引系统应该如何设计
- mysql索引系统采用的数据结构是什么?
- 为什么要使用B+树
- 什么是回表
- 什么是索引覆盖
- 什么是最左匹配原则
- 什么是索引下推
- 如何利用索引进行优化
索引是什么
索引(在mysql中也叫作键)是存储引擎用于快速找到记录的一种数据结构。当表中的数据量越来越大时,索引对性能的影响愈发重要。在数据量较小且负载较低时,不恰当的索引对性能的影响可能还不明显,但是数据量逐渐增大时,性能则会急剧下降。
索引在存储时候需要哪些信息?需要存储哪些字段? key:实际数据行中存储的值
文件地址
offset:偏移量
这样格式的数据使用什么数据结构存储,K-V 哈希表、树(二叉树、红黑树、AVL树、B树、B+树)
mysql的索引系统中不是按照刚才说的结构存储的,为什么?
- OLAP(联机分析处理-对海量历史数据进行分析,产生决策性影响-数据仓库-Hive) OLTP(联机事务处理-要求在很短的时效性返回对应的结果-关系型数据库-mysql、oracle、db2)
哈希冲突会造成数据散列不均匀,会产生大量的线性查询,比较浪费时间。 不支持范围、当进行范围查询的时候,必须逐个遍历。对于内存空间的要求比较高
如果等值查询,那么查询比较快
在mysql中有没有hash索引
- memory存储引擎使用的hash索引
- innodb支持自适应hash
索引使用常见的数据结构
常见的索引使用的数据结构是树结构,首先我们来介绍下最经典的二叉树。
先来介绍下二叉树的特点:
-
- 二叉树的时间复杂度为 O(n)
-
- 一个节点只能有两个子节点。即度不超过2
-
- 左子节点 小于 本节点,右子节点 大于 本节点
随着数据的插入,发现树的深度在变深,树的深度越深,意味着IO次数越多,影响数据读取的效率。
如果所有的索引文件放到内存,断电怎么办,索引文件丢失,需要重新创建索引。
索引是存储在磁盘中,但是会预先加载到内存中,而且在加载时是分页加载的。内存是稀缺资源,不可能一下子读取过来——>分块读取、分页读取
保证树平衡,左子树、右子树高度差距不要太高。
ALV平衡树:左子树、右子树高度差距不要太多,不能超过1,通过浪费插入性能,带来查询性能
红黑树:二叉平衡树
不管是BST,AVL 红黑树,当插入足够多的数据节点时,比如一万个,一亿个节点,会导致当前树变高,IO就会变高,查询就会变慢。
为什么树会变高,一个节点只允许插入左右
B-Tress树:
指针指向磁盘地址
问题:在mysql中B+树种占多少层: 千万级别,3~4层足够了
注意:在B+Tree上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有叶子节点(即数据节点)之间是一种链式环结构,因此可以对B+Tree进行两种查找运算:一种是对于主键的范围查找和分页查找,另一种是从根节点开始,进行随机查找。
创建索引时候用int还是varchar好?
int占4个字节,varchar占多少由自己指定。如果varchar大小小于4个字节用varchar好。因为当前占用空间越大,磁盘块范围越小,3个乘积就会变小。尽量减少索引中key值的空间大小。
mysql如果用了id做了主键索引,id是否要自增? 索引维护,页分裂,页合并
一个表中可以有多少个索引?
肯定不是一个索引,可以根据用户需要来创建索引,如果一个表中有多个索引,那么数据要存储几份? 一个表中无论有多少索引,数据只存一份。
如果数据只存储一份的话,那么其他索引怎么检索到数据呢? 回表。
数据在进行插入时,必须要跟索引存储在一起的,在Innodb的存储引擎中。
如果表中有主键,数据和主键一起,如果没有主键,跟唯一键放在一起。如果没有唯一键,会生成6字节的rowid。数据和rowid放在一起。无论如何,总是需要索引列。
其他的非数据所在索引列的B+树中,叶子节点放的数据都是数据所在索引的key值。
聚簇索引和非聚簇索引
数据和索引是否是放在一起的,如果是就是聚簇索引,如果不是就是非聚簇索引。