使用索引时最有效的途径是直接搜索组域。通过该访问方法,MySQL使用某些关键字排序的索引类型(例如,B-树)的属性。该属性允许使用 索引中的查找组而不需要考虑满足所有WHERE条件的索引中的所有关键字。既然该访问方法只考虑索引中的关键字的一小部分,它被称为松散索引扫描。如果没有WHERE子句, 松散索引扫描读取的关键字数量与组数量一样多,可以比所有关键字数小得多。如果WHERE子句包含范围判断式(关于range联接类型的讨论参见7.2.1节,“EXPLAIN语法(获取关于SELECT的信息)”), 松散索引扫描查找满足范围条件的每个组的第1个关键字,并且再次读取尽可能最少数量的关键字。在下面的条件下是可以的:
· 查询针对一个单表。
· GROUP BY包括索引的第1个连续部分(如果对于GROUP BY,查询有一个DISTINCT子句,则所有显式属性指向索引开头)。
· 只使用累积函数(如果有)MIN()和MAX(),并且它们均指向相同的列。
· 索引的任何其它部分(除了那些来自查询中引用的GROUP BY)必须为常数(也就是说,必须按常量数量来引用它们),但MIN()或MAX() 函数的参数例外。
此类查询的EXPLAIN输出显示Extra列的Using indexforgroup-by。
下面的查询提供该类的几个例子,假定表t1(c1,c2,c3,c4)有一个索引idx(c1,c2,c3):
SELECT c1, c2 FROM t1 GROUP BY c1, c2;
SELECT DISTINCT c1, c2 FROM t1;
SELECT c1, MIN(c2) FROM t1 GROUP BY c1;
SELECT c1, c2 FROM t1 WHERE c1 < const GROUP BY c1, c2;
SELECT MAX(c3), MIN(c3), c1, c2 FROM t1 WHERE c2 > const GROUP BY c1, c2;
SELECT c2 FROM t1 WHERE c1 < const GROUP BY c1, c2;
SELECT c1, c2 FROM t1 WHERE c3 = const GROUP BY c1, c2;
由于上述原因,不能用该快速选择方法执行下面的查询:
1. 除了MIN()或MAX(),还有其它累积函数,例如:
SELECT c1, SUM(c2) FROM t1 GROUP BY c1;
2. GROUP BY子句中的域不引用索引开头,如下所示:
SELECT c1,c2 FROM t1 GROUP BY c2, c3;
3. 查询引用了GROUP BY部分后面的关键字的一部分,并且没有等于常量的等式,例如:
SELECT c1,c3 FROM t1 GROUP BY c1, c2;