10.2 const
通过主键或者唯一二级索引来定位一条记录的访问方法定义为const
10.3 ref
搜索条件为二级索引列与常数进行等值比较,形成的扫描区间为单点扫描区间,采用二级索引来执行查询的访问方法称为ref
对于普通的二级索引来说,通过索引列进行等值比较后可能会匹配到多条连续的二级索引记录,而不是像主键索引或者唯一二级索引那样最多只能匹配一条记录,所以这种ref
访问方法比const
差一些
- 在二级索引列允许存储
NULL
值时,无论是普通的二级索引,还是唯一二级索引,它们的索引列并不限制NULL
值的数量,所以在执行包含key IS NULL
形式的搜索条件的查询时,最多只能使用ref
访问方法,而不能使用const
访问方法 - 对于索引列中包含多个列的二级索引来说,只要最左边连续的列是与常数进行等值比较,就可以采用
ref
访问方法
如果索引列中最左边连续的列不全是等值比较的话,就不能称为
ref
了
10.4 ref_or_null
值为NULL的记录会被放在索引的最左边
如果不仅要找出某个二级索引列的值等于某个常数的记录,而且还要把该列中值为NULL
的记录也找出来,这种访问方法称为ref_or_null
10.5 range
使用索引执行查询时,对应的扫描区间为若干个单点扫描区间或者范围扫描区间的访问方法称为range
10.6 index
扫描全不二级索引记录且不需要回表的访问方法称为index
,如果添加了“ORDER BY 主键”的语句,也会被认定为index
访问方法
10.7 all
全表扫描称为all
访问方法
10.8 注意事项
如果有多个索引可以使用,优化器会通过访问表中的少量数据或者直接根据事先生成的统计数据,来计算扫描区间包含多少条记录,选择成本更小的那个扫描区间对应的索引执行查询
10.8.2 索引合并
1、Intersection
索引合并
SELECT * FROM single_table WHERE key1='a' AND key3='b';
这里可以使用idx_key1
或者idx_key3
,还有一种方案是索引合并:同时使用idx_key1
和idx_key3
执行查询
分别在两个索引中查找满足条件的二级索引记录,然后从两者的操作结果中找出id
列值相同的记录,然后再根据这些公有的id
值执行回表操作,这样可能省下很多回表操作带来的开销,注意这里从两个索引获取到的记录都是按照id
排序的
如果在使用某个二级索引执行查询时,从对应的扫描区间中读取出的二级索引记录不是按照主键值排序的,则不可以使用Intersection
索引合并来执行查询
Intersection索引合并指的就是对从不同索引中扫描到的记录的id值取交集,只为这些id值执行回表操作,要求按照主键值排序是因为
- 从两个有序集合中取交集比从两个无序集合中取交集要容易得多
- 这样取交集后的
id
值也是有序的,执行回表操作时不是随机IO,从而提高效率
2、Union
索引合并
SELECT * FROM single_table WHERE key1='a' OR key3='b';
对于这种情况也可以使用索引合并,先分别从两个索引中读取满足条件的二级索引记录,然后根据二级索引记录的id
值在两者的结果中进行去重,再根据去重后的id值执行回表操作,这样重复的id
值只需回表一次
Union索引合并指的就是对从不同索引中扫描到的记录的id值取并集,为这些id值执行回表操作
同样,如果取得的二级索引记录不是有序的,也不能使用Union索引合并
3、Sort-Union
索引合并
SELECT * FROM single_table WHERE key1<'a' OR key3>'z';
这里从两个索引中获取到的记录不是按主键值排序的,也就不能用Union
索引合并,但可以取出二级索引记录后先按主键值排序,再索引合并
先对从各个索引中扫描到的记录按主键值排序,再按照执行Union
索引合并的方式执行查询,这种访问方式称为Sort-Union
索引合并