表结构信息:

mysql> show create table tb\G
*************************** 1. row ***************************
Table: tb
Create Table: CREATE TABLE `tb` (
`c` int(11) DEFAULT NULL,
`d` int(4) DEFAULT NULL,
`e` varchar(32) DEFAULT NULL,
KEY `c` (`c`),
KEY `c_2` (`c`,`d`),
KEY `c_3` (`c`,`d`,`e`),
KEY `c_4` (`c`,`e`),
KEY `e` (`e`,`c`,`d`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

表中的数据:

mysql> select * from tb;
+------+------+------+
| c | d | e |
+------+------+------+
| 2 | 40 | b |
| 1 | 10 | a |
| 2 | 30 | a |
| 1 | 10 | a |
| 3 | 30 | a |
| 1 | 10 | c |
| 1 | 50 | c |
| 2 | 50 | c |
+------+------+------+
8 rows in set (0.00 sec)

1. group by 算法: 先分组 还是 先排序。使用order by null可以禁用排序。

2. 单表group by 算法(不考虑覆盖索引)

(1) where 条件只含有group by, 视group by的个数而定,建立单列索引,或者组合索引。

(2) where 条件中含有等值(=)和group by,例如 where a = 1 group by b, c , 建立组合索引(a,b,c)。

(3) where 条件中含有范围( >,<,in)和group by

第一种情况,group by 中的字段包括范围字段值,比如 where c < 4 and c > 1 group by c,d ,建立组合索引(c,d);

第二种情况,group by 中的字段和范围字段都不一样。到底是优先选取小的结果集合,还是优先避免临时表、排序,这里有一个权衡的问题。

比如下面的例子:

mysql> explain select * from tb where e > 'a' group by c,d;
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------------------------------------------+
| 1 | SIMPLE | tb | range | e | e | 99 | NULL | 7 | Using where; Using index; Using temporary; Using filesort |
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------------------------------------------+
1 row in set (0.00 sec)

mysql> explain select * from tb ignore index (e) where e > 'a' group by c,d;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | tb | index | NULL | c_2 | 10 | NULL | 14 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

(4) where 条件中含有等值(=)、范围( >,<,in)和group by,只考虑建立等值和group by字段的组合索引。

(5) group by 和 order by 一起用:

  (a) group by 的字段包含 order by 的字段,并且是前缀包含,可以按照group by 的优化去处理。(group by c,d order by c)

  (b) group by 的字段包含 order by 的字段,但不是前缀包含,可以按照group by 的优化去处理。(group by c,e order by e)

  (c) group by c,d order by e; e 是聚集函数字段,可以按照group by 的优化去处理。

下面是具体的分析:

第一种情况: group by c,d order by c ; 这种情况其实不需要order by c,因为group by本身就是按照c升序排列的。建立组合索引(c,d)即可。

第二种情况: group by c,d order by c desc; 不可避免会排序。

mysql> explain select * from tb group by c,d order by c desc;
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------+
| 1 | SIMPLE | tb | index | NULL | e | 109 | NULL | 14 | Using index; Using temporary; Using filesort |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------+
1 row in set (0.00 sec)

第三种情况:group by c,e order by e; 建立组合索引(c,e),依旧避免不了排序。个人感觉这个SQL没有什么实际业务含义。

mysql> explain select c, e,count(*) from tb group by c,e order by e;
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------+
| 1 | SIMPLE | tb | index | NULL | c_4 | 104 | NULL | 14 | Using index; Using temporary; Using filesort |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------+
1 row in set (0.00 sec)

第四种情况:group by c,d order by e;

理论上而言,如果e只是一个数据库中的一般字段,这个SQL是没有什么实际业务意义的。

但是这里的e可以是select字段中的聚集函数,这样便有现实意义了。例如:select c, d,count(*) CNT from tb  group by c,d order by CNT;

按照group by去优化即可。

mysql> select c, d,count(*) from tb group by c,d;
+------+------+----------+
| c | d | count(*) |
+------+------+----------+
| 1 | 10 | 3 |
| 1 | 50 | 1 |
| 2 | 30 | 1 |
| 2 | 40 | 1 |
| 2 | 50 | 1 |
| 3 | 30 | 1 |
| 4 | 5 | 1 |
| 4 | 13 | 1 |
| 5 | 68 | 1 |
| 5 | 88 | 1 |
| 6 | 23 | 1 |
| 6 | 73 | 1 |
+------+------+----------+
12 rows in set (0.00 sec)

3. 单表group by 算法(考虑覆盖索引)

group by一般是伴随着聚集函数的,比如count(), max(), min(), avg()等等。

如果select 字段和where中的待添加索引的字段,加起来不超过4个,可以考虑加覆盖索引。

group by调优的一些测试的更多相关文章

  1. hbase性能调优之压缩测试

    文章概述: 1.顺序写 2.顺序读 3.随机写 4.随机读 5.SCAN数据 0 性能测试工具 hbase org.apache.hadoop.hbase.PerformanceEvaluation ...

  2. order by调优的一些测试

    表结构信息:mysql> show create table tb\G*************************** 1. row *************************** ...

  3. 一次tomcat配置参数调优Jmeter压力测试记录前后对比

    使用的tomcat版本为:apache-tomcat-7.0.53 使用测试工具Jmeter版本为:apache-jmeter-2.12 1.测试前tomat的"server.xml&quo ...

  4. Tomcat调优及JMX监控

    Tomcat调优及JMX监控 实验背景 ====================================================== 系统版本:CentOS release 6.5 ( ...

  5. 成为Java GC专家(5)—Java性能调优原则

    并不是每个程序都需要调优.如果一个程序性能表现和预期一样,你不必付出额外的精力去提高它的性能.然而,在程序调试完成之后,很难马上就满足它的性能需求,于是就有了调优这项工作.无论哪种编程语言,对应用程序 ...

  6. Linux低延迟服务器系统调优

    最近做了一些系统和网络调优相关的测试,达到了期望的效果,有些感悟.同时,我也发现知乎上对Linux服务器低延迟技术的讨论比较欠缺(满嘴高并发现象):或者对现今cpu + 网卡的低延迟潜力认识不足(动辄 ...

  7. JVM 调优之 Eclipse 启动调优实战

    本文是我12年在学习<深入理解Java虚拟机:JVM高级特性与最佳实践>时,做的一个 JVM 简单调优实战笔记,版本都有些过时,不过调优思路和过程还是可以分享给大家参考的. 环境基础配置 ...

  8. MySQL慢查询查找和调优测试

    MySQL慢查询查找和调优测试,接下来详细介绍,需要了解的朋友可以参考下.本文参考自:http://www.jbxue.com/db/4376.html  编辑 my.cnf或者my.ini文件,去除 ...

  9. 测试开发mysql性能调优总结(一)

    测试开发mysql性能调优总结 mysql在创建表的时候,对每个字段选择合适的数据类型很重要! 根据个人的经验总结: 整数类型选择 INT小数类型选择 DECIMAL字符串类型选择 TEXT日期时间选 ...

随机推荐

  1. Robot Framework 环境搭建

    一.下载软件 1.安装Python 到官网,下载Python 2.7.9:https://www.python.org/downloads/,最好选择32位版本的(64位系统也支付32位版本),然后安 ...

  2. pl/sql tutorial

    http://plsql-tutorial.com/plsql-procedures.htm What is PL/SQL? PL/SQL stands for Procedural Language ...

  3. [转]剖析ASP.Net MVC Application

    http://www.cnblogs.com/errorif/archive/2009/02/13/1389927.html 为了完全了解Asp.net MVC是怎样工作的,我将从零开始创建一个MVC ...

  4. hdu 2065 "红色病毒"问题

    指数型母函数的应用 求A B C D 在规定条件下n个元素的排列个数,先写出指数型母函数 G(X) = ( 1 + x + x^2/2! + x^3/3! +... )^2 * ( 1+ x^2/2! ...

  5. mysql的学习记录

    1 MySQL -h localhost -u UserName -p Password-h不写,默认为localhost注意:最好先MySQL -h localhost -u UserName -p ...

  6. [Browsable(false)]

    1.c#方法上面的[Browsable(false)]是干吗用的? 答案:标明此对象不可被浏览,这样它就不会出现在设计器的属性窗口里了 看如下代码: /// <include file='Asp ...

  7. truncate、drop、delete区别

    速度:drop>truncate>delete 1.TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行.但 TRUNCATE ...

  8. Fragment 与 Activity 通信

    先说说背景知识: (From:http://blog.csdn.net/t12x3456/article/details/8119607) 尽管fragment的实现是独立于activity的,可以被 ...

  9. 李洪强iOS开发之OC语言构造方法

    OC语言构造方法 一.构造方法 (一)构造方法的调用 完整的创建一个可用的对象:Person *p=[Person new]; New方法的内部会分别调用两个方法来完成2件事情,1)使用alloc方法 ...

  10. LR_问题_如何将场景中的用户设置为百分比形式

    一个场景运行多个脚本时,如何按照百分比模式运行