MySQL中GROUP BY的基本实现原理

   由于 GROUP BY 实际上也同样会进行排序操作,而且与 ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作。当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算。所以,在GROUP BY 的实现过程中,与 ORDER BY 一样也可以利用到索引。

  在 MySQL 中,GROUP BY 的实现同样有多种(三种)方式,其中有两种方式会利用现有的索引信息来完成 GROUP BY,另外一种为完全无法使用索引的场景下使用。下面我们分别针对这三种实现方式做一个分析。

  1.使用松散(Loose)索引扫描实现 GROUP BY

  何谓松散索引扫描实现 GROUP BY 呢?实际上就是当 MySQL 完全利用索引扫描来实现 GROUP BY 的时候,并不需要扫描所有满足条件的索引键即可完成操作得出结果。

  下面我们通过一个示例来描述松散索引扫描实现 GROUP BY,在示例之前我们需要首先调整一下 group_message 表的索引,将 gmt_create 字段添加到 group_id 和 user_id 字段的索引中:

  以下为引用的内容:

  sky@localhost : example 08:49:45> create index idx_gid_uid_gc

  -> on group_message(group_id,user_id,gmt_create);

  Query OK, rows affected (0.03 sec)

  Records: 96 Duplicates: 0 Warnings: 0

  sky@localhost : example 09:07:30> drop index idx_group_message_gid_uid

  -> on group_message;

  Query OK, 96 rows affected (0.02 sec)

  Records: 96 Duplicates: 0 Warnings: 0

  然后再看如下 Query 的执行计划:

  以下为引用的内容:

  sky@localhost : example 09:26:15> EXPLAIN

  -> SELECT user_id,max(gmt_create)

  -> FROM group_message

  -> WHERE group_id < 10

  -> GROUP BY group_id,user_idG

  *************************** 1. row ***************************

  id: 1

  select_type: SIMPLE

  table: group_message

  type: range

  possible_keys: idx_gid_uid_gc

  key: idx_gid_uid_gc

  key_len: 8

  ref: NULL

  rows: 4

  Extra: Using where; Using index for group-by

  1 row in set (0.00 sec)

  我们看到在执行计划的 Extra 信息中有信息显示“Using index for group-by”,实际上这就是告诉我们,MySQL Query Optimizer 通过使用松散索引扫描来实现了我们所需要的 GROUP BY 操作。

时间: 2024-09-10 09:54:43

MySQL中GROUP BY的基本实现原理的相关文章

mysql中group by留下的数据是哪一条

问题描述 mysql中group by留下的数据是哪一条 group by分组后,会留下一条数据,请问留下的这条数据,我们可以指定吗?就是指定显示出来的那条数据是某组中的指定的某条数据. 解决方案 你可以group生成到i一个表中,然后你再select where加条件把你需要的查询出来 解决方案二: 你可以在group by 后面用having的,having是专门用来处理分组后的数据的,包括就显示一条数据 解决方案三: 留下的数据是它默认排序的第一条. 如果要这么做那可以把group by的

mysql中Group By 如何统计

问题描述 mysql中Group By 如何统计 数据如下: 访问时间 离开时间 2014-1-1 2014-1-2 2014-1-3 2014-2-1 2014-2-2 2014-2-8 2014-2-8 2014-3-1 2014-3-5 2014-3-5 2014-3-5 2014-4-1 2014-4-1 2014-4-10 2014-4-2 请问如何用sql计算分组显示,2-3月区间的数据 时间 ---- 访问次数 ---离开次数 2013-2 ----- 3 ----- 1 2013

mysql中group by与having合用注意事项分享_Mysql

group by函数应该的使用应该是SELECT 列表中指定的每一列也必须出现在 GROUP BY 子句中,除非这列是用于聚合函数,但是今天帮同事调试一个mysql中的group by函数,让我大跌眼镜,当时感觉不可思议,然后回来做了个简化版试验,试验过程如下: mysql表结构 复制代码 代码如下: mysql> desc t;+---+----–+--+-–+---+---+| Field | Type | Null | Key | Default | Extra |+---+----–+-

mysql中group by用法与having合用注意事项

group by函数应该的使用应该是SELECT 列表中指定的每一列也必须出现在 GROUP BY 子句中,除非这列是用于聚合函数,但是今天帮同事调试一个mysql中的group by函数,让我大跌眼镜,当时感觉不可思议,然后回来做了个简化版试验,试验过程如下: mysql表结构  代码如下 复制代码 mysql> desc t; +---+----–+--+-–+---+---+ | Field | Type | Null | Key | Default | Extra | +---+----

MYSQL中GROUP分组去除重复数据

GROUP分组去除重复数据 /**  * 清除同一专题中重复导入的数据  * @author tanteng  * @date 2014.07.27  */ public function fuck_repeat(){  set_time_limit(0);  $sql = "SELECT `id` FROM `v95_special_content` GROUP BY `specialid`,`curl` HAVING COUNT(`curl`)>1 ";  $result =

简单介绍MySQL中GROUP BY子句的使用_Mysql

 可以使用GROUP BY组值一列,并且如果愿意的话,可以将该列进行计算.使用COUNT,SUM,AVG等功能的分组列. 要了解GROUP BY子句考虑的EMPLOYEE_TBL的的表具有以下记录: mysql> SELECT * FROM employee_tbl; +------+------+------------+--------------------+ | id | name | work_date | daily_typing_pages | +------+------+---

mysql中GROUP BY 和ORDER BY 组合使用注意事项

例子 ID  uid  content  weid      addtime  1  2  3213123  12  -..      2  3  3213123  12  -.  3  2  321312  12  -  3  1  xxx  12  3232  我们的需求是从消息表中掉出来最近的用户,刚开始的时候用的是这样写的  代码如下 复制代码 SELECT f . * FROM  `enet_wechat_message` AS m LEFT JOIN  `enet_wechatfan

MYSQL中group by做分组查询并排序

那么如何解决使分组后的数据按照主键的 desc 排序输出呢? 答案有两种方法: 1.使用子查询先把表进行排序,然后对字表进行 group by 查询,此时得到的列将是子查询的得到的一条记录的列. 2.使用 max 函数对可计算最大值的列进行对比查询,这种方法将只能使的对比列按照 desc 输出,不影响其他列. 以上两种方法的结果不同,使用的时候要按需来使用. 附例子: 表 tab1 有 3 列:主键id.名称name.登录时间time id name time 1 a01 1 2 www.111

mysql中having和group by命令使用详解

利用 Mysql 中的的聚合函数 count(*) 可以实现这个功能,例如需要查询 user 表中 name 出现次数最多的记录,可以先按照 group by name 分组,用 count 算出分组里的条数,再按照 count 排序,SQL语句如下: select name,count(*) from user group by name order by count(*) DESC limit 1; 不加limit限制将返回按照name重复次数排列的数据. 在使用聚合函数之前,我们可以通过