表结构信息:

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. 如何恢复SQL Server 中的Master库

    如何恢复SQL Server 2005中的Master库 2011-05-10 16:34 Vegas Lee 博客园 我要评论(0) 字号:T | T   master库对于SQLServer来说, ...

  2. HDU1251 统计难题 Trie树

    题目很水,但毕竟是自己第一道的Trie,所以还是发一下吧.Trie的更多的应用慢慢学,AC自动机什么的也慢慢学.... #include<iostream> #include<cst ...

  3. 用 Xamarin for VS 创建 aar 文件的绑定

    预备工作:相关aar文件,Xamarin for VS一份.我这里以Android中挺火的 MaterialDesignLibrary 为例. 1.首先,创建一个Xamarin Binding Lib ...

  4. Dictionary<Key,Value>的用法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. System.Windows.Forms.AxHost.InvalidActiveXStateException”类型的异常在 ESRI.ArcGIS.AxControls.dll 中发生,但未在用户代码中进行处理

    private void CopyAndOverwriteMap() { //IObjectCopy接口变量申明 IObjectCopy objectCopy = new ObjectCopyClas ...

  6. Java文件解压之TGZ解压

    package com.alibaba.intl.batch.dependency; import java.io.File; import java.io.FileInputStream; impo ...

  7. 76. Minimum Window Substring

    题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...

  8. Android学习之-TextView的滑动效果

    textView中如何设置滚动条 在xml中定义: <TextView            android:layout_width="wrap_content"      ...

  9. [从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)【转】

    (function(){ //这里忽略jQuery所有实现 })(); 半年前初次接触jQuery的时候,我也像其他人一样很兴奋地想看看源码是什么样的.然而,在看到源码的第一眼,我就迷糊了.为什么只有 ...

  10. 使用 powershell 的 grep 过滤文本

    使用 powershell 的 grep 过滤文本 有个log文件,大小在4M左右,要求找出里面耗时超过100s 的记录.首先想到了强大的 grep ,那么就搞起. 先在网上找一下资料,这篇文章,有几 ...