为什么选择B+树作为索引结构
- Hash索引:Hash索引底层是哈希表,哈希表是一种以key-value存储数据的结构,所以多个数据在存储关系上是完全没有任何顺序关系的,所以,对于区间查询是无法直接通过索引查询的,就需要全表扫描。所以,哈希索引只适用于等值查询的场景。而B+ 树是一种多路平衡查询树,所以他的节点是天然有序的(左子节点小于父节点、父节点小于右子节点),所以对于范围查询的时候不需要做全表扫描
- 二叉查找树:解决了排序的基本问题,但是由于无法保证平衡,可能退化为链表。
- 平衡二叉树:通过旋转解决了平衡的问题,但是旋转操作效率太低。
- 红黑树:通过舍弃严格的平衡和引入红黑节点,解决了 AVL旋转效率过低的问题,但是在磁盘等场景下,树仍然太高,IO次数太多。
- B+树:在B树的基础上,将非叶节点改造为不存储数据纯索引节点,进一步降低了树的高度;此外将叶节点使用指针连接成链表,范围查询更加高效。
B+树的叶子节点都可以存哪些东西
可能存储的是整行数据,也有可能是主键的值。B+树的叶子节点存储了整行数据的是主键索引,也被称之为聚簇索引。而索引B+ Tree的叶子节点存储了主键的值的是非主键索引,也被称之为非聚簇索引。
注意:
MySQL InnoDB一定会建立聚簇索引,把实际数据行和相关的键值保存在一块,这也决定了一个表只能有一个聚簇索引,即MySQL不会一次把数据行保存在二个地方。
- InnoDB通常根据主键值(primary key)进行聚簇
- 如果没有创建主键,则会用一个唯一且不为空的索引列做为主键,成为此表的聚簇索引
- 上面二个条件都不满足,InnoDB会自己创建一个虚拟的聚集索引
- 正因为InnoDB将数据保存在一处,因此其插入速度严重依赖插入顺序。按照主键顺序插入无疑是最快的。如果不是按照主键插入,建议加载完成后最好使用OPTIMIZE TABLE重新组织一下表。
什么是聚簇索引
总结下,聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。当表中有聚簇索引时,它的数据行实际上存放在索引的叶子页中。
什么是覆盖索引
- 一个查询语句的执行只用从索引中就能够取得,不必回表读取。也可以称之为实现了索引覆盖。
为什么不推荐使用select *
- 增加了不必要的网络开销。在查询巨量时,数据传输是十分耗时的。
- 我们在上面已经提到了覆盖索引。显然使用select *导致无法使用覆盖索引。
什么是最左匹配原则
最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。
注意:
但是这不意味着不按照索引顺序写的查询条件就会100%导致不走索引。MySQL的性能优化器会判断纠正这条sql语句该以什么样的顺序执行效率最高,最后才生成真正的执行计划。
查询在什么时候不走(预期中的)索引
- 模糊查询 %like
- 索引列参与计算,使用了函数
- 非最左前缀顺序
- where对null判断
- where不等于
- or操作有至少一个字段没有索引
- 需要回表的查询结果集过大(超过配置的范围)