MySQL有关Group By的优化

    昨天我写了有关MySQL的loose index scan的相关博文(http://www.cnblogs.com/wingsless/p/5037625.html),后来我发现上次提到的那个优化方法中主要的目的就是实现loose index scan,而在执行计划的层面上看,Extra信息中应该是“Using index for group-by”。这样看来,可能MySQL在处理distinct时和group by用了一样的优化手段,即走索引,进行loose index scan。那么今天我研究了一下官方文档,发现确实如此。html

    其实对于group by来说,最通常的实现方法就是进行一次全表扫描,将全部的group by的行按照顺序存放在一个temporary table中,而后在进行分组识别或者进行聚合操做。这样问题就是太复杂,时间上要很久,空间上的消耗也不小。这时,MySQL能够利用索引来优化group by。less

    这里就能够讲讲什么叫作loose index scan了,根据官方的定义,这种方法只须要扫描索引中的少部分数据,而不是全部知足where条件的数据,因此这个方法叫作loose index scan。函数

    下面是什么状况下可使用loose index scan的状况:测试

    1 单一表查询优化

    2 Group by中只有最左前缀列,没有其余列spa

    3 只支持max和min聚合,并且,要聚合的列必须是group by中列所在的索引。code

    4 未被group by引用的索引其余部分必须是常量(这句我不是很理解)htm

    5 不支持前缀索引。blog

    假设t1(c1, c2, c3, c4)表有一个索引包括c1, c2, c3列,如下这些查询都是能够进行loose index scan的:索引

    

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;

    这些都是抄的官方文档,正确性未彻底验证。  

    下面这些SQL都没有办法使用loose index scan:

    

-- 由于聚合函数不是max或者min
SELECT c1, SUM(c2) FROM t1 GROUP BY c1;

-- 由于不符合最左前缀原则
SELECT c1, c2 FROM t1 GROUP BY c2, c3;

-- 查询涉及到了索引的一部分,紧跟group by中的列,可是没有常量等值语句,加上 
SELECT c1, c3 FROM t1 GROUP BY c1, c2;WHERE c3 = const就行了const就行了

     另一些聚合函数也是能够用到loose index scan的,好比:AVG(DISTINCT), SUM(DISTINCT), 和COUNT(DISTINCT)

     如下这些语句也能够:

     

SELECT COUNT(DISTINCT c1), SUM(DISTINCT c1) FROM t1;

SELECT COUNT(DISTINCT c1, c2), COUNT(DISTINCT c2, c1) FROM t1;

      不少语句都是从5.7的文档上摘抄下来的,正确性没有获得验证,虽然说官方文档是权威,可是尽信书不如无书,以及纸上得来终觉浅,绝知此事须躬行,明天周末,我逐条测试,而后再更。

相关文章
相关标签/搜索