zoukankan      html  css  js  c++  java
  • 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。那么今天我研究了一下官方文档,发现确实如此。

        其实对于group by来讲,最一般的实现方法就是进行一次全表扫描,将所有的group by的行按照顺序存放在一个temporary table中,然后在进行分组识别或者进行聚合操作。这样问题就是太复杂,时间上要好久,空间上的消耗也不小。这时,MySQL可以利用索引来优化group by。

        这里就可以讲讲什么叫做loose index scan了,根据官方的定义,这种方法只需要扫描索引中的少部分数据,而不是所有满足where条件的数据,所以这个方法叫做loose index scan。

        下面是什么情况下可以使用loose index scan的情况:

        1 单一表查询

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

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

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

        5 不支持前缀索引。

        假设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中的列,但是没有常量等值语句,加上 WHERE c3 = const就好了
    SELECT c1, c3 FROM t1 GROUP BY c1, c2;

         另外一些聚合函数也是可以用到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的文档上摘抄下来的,正确性没有得到验证,虽说官方文档是权威,但是尽信书不如无书,以及纸上得来终觉浅,绝知此事须躬行,明天周末,我逐条测试,然后再更。

  • 相关阅读:
    Too many authentication failures for xxxx_username
    [linux]ngrep命令、常见用法
    pip安装icu失败:Command "python setup.py egg_info" failed with error code 1 in
    peewee insert 数据时报错:'buffer' object has no attribute 'translate'
    SQL Server 加密案例解析
    MyBatis学习笔记
    01-hibernate注解:类级别注解,@Entity,@Table,@Embeddable
    01-hibernate注解:类级别注解准备工作
    11-hibernate,单表GRUD操作实例
    10-hibernate单表操作-组件属性
  • 原文地址:https://www.cnblogs.com/wingsless/p/5040620.html
Copyright © 2011-2022 走看看