1.二级索引
给主键字段之外的字段建立索引,称之为二级索引。
二级索引和聚簇索引的原理是一样的,也是一颗b+树,区别是叶子节点虽然是数据页,但存放的是主键id+索引字段值
同时,叶子节点的上一层节点存的是最低层索引页,存放索引字段最小值和数据页编号
再上一层节点页是索引页,存放的是索引字段最小值和索引页编号,索引页还可以再次增加层级。
查询数据的时候,先根据索引字段二分法往下找,从数据页,找到了主键id,再回表,根据主键id从主键的聚簇索引里面去找到这条数据。
2.常见的索引匹配规则
1.等值匹配规则
where语句中的几个字段名称和联合索引的字段完全一样,而且都是基于等号的等值匹配,那就能匹配上索引,即使where语句中的字段的顺序和联合索引里的字段顺序不一致也可以,数据库会自动优化为按联合索引的字段顺序去找。
2.最左侧列匹配
假设联合索引是KEY(class_name, student_name, subject_name),那么不一定必须要在where语句里根据三个字段来查,其实只要根据最左侧的部分字段来查,也是可以的。
比如select * from student_score where class_name=’’ and student_name=’’,就查某个学生所有科目的成绩。
但是select * from student_score where subject_name=’’,就不行了,因为联合索引的B+树里,是必须先按class_name查,再按student_name查,不能跳过前面两个字段,直接按最后一个subject_name查的。
另外select * from student_score where class_name=’’ and subject_name=’’,那么只有class_name的值可以在索引里搜索,剩下的subject_name是没法在索引里找的,道理同上。
所以在建立索引的过程中,必须考虑好联合索引字段的顺序,以及平时写SQL的时候要按哪几个字段来查。
3.最左前缀匹配原则
如果用like语法来查,比如select * from student_score where class_name like ‘1%’,查找所有1打头的班级的分数,是可以用到索引的。
在联合索引的B+树里,都是按照class_name排序的,给出class_name的确定的最左前缀就是1,然后后面的给一个模糊匹配符号,也可以基于索引来查找的。
但如果写class_name like ‘%班’,在左侧用一个模糊匹配符,那就不能用索引了,因为不知道最左前缀是什么。
4.范围查找规则
用select * from student_score where class_name>‘1班’ and class_name<'5班’这样的语句来范围查找某几个班级的分数。
这也可以用到索引,因为索引的最下层的数据页都是按顺序组成双向链表的,所以可以先找到’1班’对应的数据页,再找到’5班’对应的数据页,两个数据页中间的那些数据页,就是在范围内的数据了。
但是select * from student_score where class_name>‘1班’ and class_name<‘5班’ and student_name>’’,这里只有class_name是可以基于索引来找的,student_name的范围查询是没法用到索引的!
这也是一条规则,就是where语句里如果有范围查询,那只有对联合索引里最左侧的列进行范围查询才能用到索引。
5.等值匹配+范围匹配的规则
select * from student_score where class_name=‘1班’ and student_name>’’ and subject_name<’‘这样的SQL,首先可以用class_name在索引里精准定位到一些数据,接着这些数据里的student_name都是按照顺序排列的,所以student_name>’‘也会基于索引来查找,但是接下来的subject_name<’'是不能用索引的。
综上所述,一般写SQL语句,都是用联合索引的最左侧的多个字段来进行等值匹配+范围搜索,或者是基于最左侧的部分字段来进行最左前缀模糊匹配,或者基于最左侧字段来进行范围搜索,这就要写符合规则的SQL语句,才能用上建立好的联合索引。