MySQL执行查询语句的方式称为访问方法(access method)。
const
通过主键或唯一二级索引列定位一条记录的方法叫const,这种方法要求主键列或者唯一二级索引列与一个常数进行等值比较时才有效。注意,使用唯一二级索引且搜索条件为IS NULL无效。
例如:
SELECT * FROM single_table WHERE id = 10086; SELECT * FROM single_table WHERE key2 = 123;
ref
通过普通二级索引列与常数进行等值比较,形成单点扫描区间,使用该二级索引来执行查询的方法叫ref。查询IS NULL也属于ref。联合索引满足最左匹配也可采用ref。
例如:
SELECT * FROM single_table WHERE key1 = 'a'; SELECT * FROM single_table WHERE key_part1 = 'a' AND key_part2 = 'b';
注意,二级索引查询时,每获取到一条二级索引记录,就会立刻执行回表。
ref_or_null
既通过二级索引与常数进行等值比较,又判断IS NULL,这种方法叫ref_or_null。
例如:
SELECT * FROM single_table WHERE key1 = 'abc' OR key1 IS NULL;
注意:值为NULL的记录会被放在索引的最左边。
range
形成扫描区间为若干个单点扫描区间或范围扫描区间的执行查询的方法叫range。
例如:
SELECT * FROM single_table WHERE key2 IN (1000, 2000); SELECT * FROM single_table WHERE key2 >=20 AND key2 <=30;
index
执行扫描全部二级索引记录的方法叫index。注意,查询列表覆盖索引,也就是不会产生回表。扫描二级索引全部记录的执行成本比扫描聚簇索引全部记录小很多。
例如:
SELECT key_part1, key_part2, key_part3 FROM single_table WHERE key_part2 = 'a';
注意:根据主键排序也是index。index是对二级索引的全范围扫描,并非全表扫描。
all
扫描全部聚簇索引记录的访问方法称all。
index merge
MySQL可能为多个索引生成扫描区间,获得主键,再回表。
-
Intersection索引合并
两个索引的主键按顺序排列,取交集
例如:
SELECT * FROM single_table WHERE key1 = 'a' AND key3 = 'b';
不管使用key1列的索引还是使用key3列的索引,都逃不过全票扫描。那就同时使用两个索引分别查找二级索引中的记录,然后将获取到的主键值取交集,然后根据这些主键值进行回表。
注意:从每个索引中获取到的二级索引记录都要按照主键排序。否则取交集开销过大,乱序主键回表会造成随机I/O。
-
Union索引合并
两个索引的主键按顺序排列,取交集
例如:
SELECT * FROM single_table WHERE key1 = 'a' OR key3 = 'b';
同时使用key1列和key3列的索引,分别获取到二级索引记录,将主键值取并集,然后根据这些主键值进行回表。
注意:从每个索引中获取到的二级索引记录都要按照主键值排序。否则乱序去重开小更大,回表也会造成随机I/O。
-
Sort-Union索引合并
索引的主键没有按顺序,但是可以主动排序,再Union。
例如:
SELECT * FROM single_table WHERE key1 < 'b' OR key3 > 'y';
显然根据key1列的索引和key3列的索引分别获得到的二级索引记录并不是按主键值排序的,那就先将这些记录按照主键进行排序,再进行Union的步骤。