索引是什么?
MySQL索引的变化过程
上面这张图左边是存储数据的表格(table),右边是存储对应数据的一颗二叉搜索树(一个节点的左边的子节点永远小于该节点,右边的子节点永远都大于该节点)。
select * from table where Col2 = 23
上面是查询Col2=23的一条SQL,当我们对table没有建索引的时候,会从第一个元素,一个个比较,要比较七次才能查询出结果,查询效率很慢,然后最开始的索引结构是把Col2数据是变成一颗二叉搜索树,如下图:
这样查询23我们只需要找寻四次,但是不稳定,我们把Col1的数据组成二叉搜索树,如下图:
假设我们找7,这个查找次数变成了7,所以二叉搜索树不稳定。后面有人使用红黑树(一种自动平衡层高的树)进行改良,还是拿我们的Clo1的数据进行实验生成树,如下图:
根据红黑树的结构我们找7只需要四次就能找到,且稳定,但是红黑树只能针对少量数据,数据太多了也会导致查询效率严重降低,根据前面几个案列,我们可以发现影响查询效率主要是树的层高,那只要不让树的层高不太高就可以提升我们对大量数据查询的优化了,这时B树就出现了,如下图:
B树:
-
叶节点具有相同的深度,叶节点的指针为空
-
所有索引元素不重复
-
节点中的数据索引从左到右递增排列
节点多放几个数据,就可以很好的控制层高了,但是在MySQL中节点存储数据,导致一个节点放的数据较少。这时就有了我们最终的数据结构B+树,如下图:
B+树(变形B树)
1. 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引,常驻内存
2. 叶子节点包含索引字段,存放在硬盘中。
3. 叶子节点用指针连接,提高区间访问的性能
MySQL常见存储引擎
MylSAM
MyISAM索引文件(后缀是.MYI的文件)和数据文件(后缀是.MYD文件)是分离的(非聚集:索引和数据分开存储)。
InnoDB
-
InnoDB索引实现(聚集:数据和索引一起存储)
-
表数据文件本身就是按B+树组织的一个索引结构文件
-
聚集索引-叶节点包含了完整的数据记录
聚集索引:
非聚集索引:
为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?
不建主键的话,MySQL会自己维护一个主键,所以还是自己建主键好一些,因为整型的计算效率高一些,占用的空间少。
为什么非主键索引结构叶子节点存储的是主键值?
一致性和节省存储空间
Hash索引
- 对索引的key进行一次hash计算就可以定位出数据存储的位置
- 很多时候Hash索引要比B+ 树索引更高效
- 仅能满足 “=”,“IN”,不支持范围查询
- hash冲突问题
联合索引
联合索引是关联多个字段组合成为一个索引。
该索引会拿这些字段先后去创建索引结构,就拿下面案列来说,是以name,age,position创建联合索引,首先拿name等于Bill的,然后在是Bill的age,最后才是position。
联合索引需要坚守最左匹配原则,例如上面介绍的索引的索引为第一个字段进行排序,如果相等则按照第二个字段进行排序,该过程不允许中断。
所以写查询条件一定要按照name,age,position的顺序来写。