1.索引:索引是帮助mysql高效获取数据的排好序的数据结构;
2.索引的数据结构:
- 二叉树
- 红黑树
- Hash表
- B tree
- B+ tree
col1 | col2 |
---|---|
1 | 34 |
2 | 77 |
4 | 91 |
5 | 22 |
6 | 89 |
7 | 23 |
上面表格假设是mysql数据库中一张表,我们执行select * from t where t.col1=6,毫无疑问需要执行6次和磁盘i/o,才能找到我们需要的值。极大的浪费性能,假如我们使用二叉树数据结构建立索引,我们都知道二叉树的存储数据的时候右边的值大于左边,我们会得到如下结构:
使用二叉树存储递增德索引会变成一个列表,如果执行上面的语句查询col1为6的话,同样还是执行6次,所以mysql底层是不使用二叉树来维护索引结构的。
如果使用红黑树来存储索引数据结构,会变成如下结果:
红黑树也满足二叉树的特性,所以又称为二叉平衡树,当分支的数据比较多的时候,会自动平衡树缺点是如果数据量大的话,叶子节点就会特别多,层级也会特别多,查询的时候还是会浪费性能。mysql早期版本使用过红黑树,后来的版本就没使用过。
办法总比困难多,如果横向能存储更多的元素的话,树的高度就会越小。
B-tree的特点:
- 叶子节点具有相同的深度,叶子节点的指针为空
- 所有索引元素不重复
- 节点中的数据索引从左到右递增排列
B树的存储索引结构如下表:
每次能从节点中拿取更多的元素放到内存中。
但是mysql的索引存储使用的还不是这种,使用了性能更为搞笑的B+树。
特点: - 非叶子节点不存储data,只存储索引,可以放更多的索引(冗余)
- 叶子节点包含所有索引字段
- 叶子节点用指针连接,提高区间的访问性能
- 叶子节点存储所有索引元素和元素地址
- 非叶子节点只是为了冗余叶子节点的一些表头数据
B+树的存储结构如下:
所有元素都是从左到右一次递增,B+树会提前把没有data的索引加载到内存中,在内存中查找完成后只需要一次的磁盘I/O就可以load数据。效率特别的高。
B树和B+树的区别:
B树没有维护指针,没办法支撑范围查找,没有冗余索引,同等大小的情况下存储更多的索引,层级就会越小。
Hash索引:数组+链表
- 对索引的key进行一次hash计算,就可以定为出数据存储的位置
- 很多时候hash索引比B+树索引更高效
- 但是仅能满足 “=”,“in” 不支持范围查询
- hasn冲突问题
为什么建议Innodb表表必须建主键,并且推荐使用整型的自增主键?
如果不建立主键的话,mysql会自动找一列(唯一索引)组织数据,如果没有找到的话,mysql会自动维护一个隐藏列组织数据,如果这些事情我们不做的话,全是mysql帮我们做了,而我们优化的时候就是要mysql少做一些额外的工作,所以我们建表的时候需要维护一个主键,因为B+树存储索引是从左往右依次递增,如果设置成uuid的话,还得比较大小再去维护数据,这大大增加了mysql的工作,所以我们一般是bigint自增。
数据库表设置一个索引就会维护一个B+树,增加删除都需要去维护,所以我们不需要过多的设置索引。尽量使用联合索引。