我的博客原地址:blog.csdn.net/weixin_3931…
索引
什么是索引?
一句话索引是排好序的一种数据结构。 因为排好序MYSQL就可以快速的查找。对于有序的数据查找是非常快的。
MYSQL有哪几种数据结构的索引?
- 二叉树
- 红黑树
- Hash表
- B-Tree
二叉树
每个节点下可以挂两个节点,左边比自己小右边比自己大。
缺点: 有可能数据都比34大,或者都比34小的情况下,就变成了链表。
极端情况下退化成链表
红黑树
解决了二叉查找树的线性问题;进行平衡性
缺点: 随着数据量的增加例如1000w条数据。这个树的的高度非常的高。
B-Tree
上面看到二叉树还是红黑树,缺点都是 每个节点下只能挂两个子节点。那么数据量多的时候就会导致树的高度变的很高。B-Tree 通过增加每个节点下能挂的子节点树。来降低树的高度。
思考: 那我只要将每个节点下挂超级多的子节点不就能解决树的高度问题?
B树与B+树有什么区别?
MYSQL为什么不用B树而用B+树(MYSQL用B+树不知道要挨打。)?
区别:
- B+树的非页子(最底层的节点)节点不存储数据
- B+树的页子节点之间是会相互连接的。
前提知识: 操作系统在读取数据的时候都是按页为单位读取的。而不是你访问多少数据就读多少数据。 如果每次访问磁盘的一页数据刚好就是我们的非页子节点所占用的数据(以int数据类型。约1k多个子节点)。
- 我们要减少访问磁盘的次数
- 我们要充分利用这一页的数据 计算:三层的1k叉树能放多少数据? 1k *1k *1k = 10亿条数据。
所以非页子节点不放数据的话,才能保证每个节点下存储更多的子节点位置数据。这样才能保证树的高度3层就能存储10亿条数据。一般来说根节点mysql都会缓存在内存中。所以查询到数据,只需要访问两次的磁盘页。即只要访问两次磁盘。
为什么底层的页子节点之间要相互连接呢?
想象一下,下面这条sql语句怎么去查找数据。
select * from account where id >10;
- 第一步肯定找到id=10的那个叶子节点。
- 如果底层数据都是连接起来,这时候只要像链表一样向后遍历即可。
- 如果底层叶子节点没有链接,此时就比较麻烦了。
所以叶子节点之间连接,主要是为了范围查询。
不同存储引擎的索引有什么不同?
主要讨论下面两种存储引擎:
InnoDB
- 表数据文件本身就是按B+Tree组织的一个索引结构文件
- 聚集索引-叶节点包含了完整的数据记录
- 为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?因为数据都保存在主键索引文件中。如果不建自增主键,mysql也会生成一个rowid作为主键。
- 为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)