表结构信息:

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. OpenResty 反向代理的用法与技巧

    Nginx最开始是作为反向代理被熟知的,基于它的OpenResty的自然也是支持反向代理的,下面我们就来看看它的一些基本用法以及在使用过程中的一些技巧. 一.基本用法 在业务环境中,可能会将OpenR ...

  2. lintcode :Binary Tree Preorder Traversal 二叉树的前序遍历

    题目: 二叉树的前序遍历 给出一棵二叉树,返回其节点值的前序遍历. 样例 给出一棵二叉树 {1,#,2,3}, 1 \ 2 / 3 返回 [1,2,3]. 挑战 你能使用非递归实现么? 解题: 通过递 ...

  3. sql sever 2000

    sql sever 2000安装图解 浏览:15396 | 更新:2011-12-14 16:33 1 2 3 4 5 6 7 分步阅读 做为入门系统管理员,sqlsever2000是必会项目,因为市 ...

  4. 从一次面试经历谈PHP的普通传值与引用传值以及unset

    关于这个概念一般都会在PHP的第一堂课说变量的时候给介绍,并且我以前还给其他PHPer介绍这个概念.但是作为一个工作一段时间的PHPer的我,竟然在面试的时候一下子拿不定主意最后还答错了,很觉得丢脸( ...

  5. windows下编译FreeSwitch

    FreeSWITCH的是一个跨平台的开源电话交换平台 windows版本:win7 64位的操作系统 [下载] 我下载的是release版本,下载的文件是freeswitch-1.4.20.zip,下 ...

  6. linux shell 命令学习(1) du- estimate file space usage

    du - estimate file space usage , 计算文件的磁盘大小 语法格式: du [OPTION] ... [FILE] 描述: 汇总每个文件的磁盘大小, 递归汇总目录的大小, ...

  7. [iOS]iPhone进行真机测试(基础版)

    买完688个人开发者账号之后,如何进行真机测试呢??看下面 1.打开https://developer.apple.com 然后,输入我们买过688点那个App ID帐号和密码哦!!一定是要支付过的! ...

  8. Linux 查看版本详情

    内核版本的信 uname -a -a选项表示察看所有的信息,但是从输出信息可以看出来,uname看到的版本信息,只是内核版本的信息,而不是发行版的版本信息 查看发行版信息 $cat /etc/issu ...

  9. 设计模式之Inheritance versus Parameterized Types 继承和参数化类型

    Another (not strictly object-oriented)technique for reusing functionality is through parameterized t ...

  10. Storm集群的搭建

    storm的环境和hadoop的环境没有任何关系 1.安装Zookeeper集群 2.解压storm 3.修改文件conf/storm.yaml 3.1.配置zookeeper服务器 storm.zo ...