mysql group原理_MySQL Group By 实现原理分析

【IT168 专稿】由于 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 字段的索引中:

1 sky@localhost: example08:49:45>createindexidx_gid_uid_gc2 3 ->ongroup_message(group_id,user_id,gmt_create);4 5 Query OK, rows affected (0.03sec)6 7 Records:96Duplicates:0Warnings:08 9 sky@localhost: example09:07:30>dropindexidx_group_message_gid_uid10 11 ->ongroup_message;12 13 Query OK,96rows affected (0.02sec)14 15 Records:96Duplicates:0Warnings:0

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

1 sky@localhost: example09:26:15>EXPLAIN2 3 ->SELECTuser_id,max(gmt_create)4 5 ->FROMgroup_message6 7 ->WHEREgroup_id<108 9 ->GROUPBYgroup_id,user_id\G10 11 ***************************1. row***************************12 13 id:114 15 select_type: SIMPLE16 17 table: group_message18 19 type: range20 21 possible_keys: idx_gid_uid_gc22 23 key: idx_gid_uid_gc24 25 key_len:826 27 ref:NULL28 29 rows:430 31 Extra: Usingwhere; Usingindexforgroup-by32 33 1rowinset(0.00sec)

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

下面这张图片描绘了扫描过程的大概实现:

60e1c183203730864c2d7c8620d158e4.png

要利用到松散索引扫描实现 GROUP BY,需要至少满足以下几个条件:

◆GROUP BY 条件字段必须在同一个索引中最前面的连续位置;

◆在使用GROUP BY 的同时,只能使用 MAX 和 MIN 这两个聚合函数;

◆如果引用到了该索引中 GROUP BY 条件之外的字段条件的时候,必须以常量形式存在;

为什么松散索引扫描的效率会很高?

因为在没有WHERE子句,也就是必须经过全索引扫描的时候, 松散索引扫描需要读取的键值数量与分组的组数量一样多,也就是说比实际存在的键值数目要少很多。而在WHERE子句包含范围判断式或者等值表达式的时候, 松散索引扫描查找满足范围条件的每个组的第1个关键字,并且再次读取尽可能最少数量的关键字。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346125.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用AWS Lambda的CloudWatch事件通知

CloudWatchEvents的主要用例是跟踪整个AWS基础架构中的更改。 当前&#xff0c;它支持在Auto Scaling组&#xff0c;EC2&#xff0c;EBS和其他各种事件中发出的事件。 为了对这些事件进行有意义的处理&#xff0c;我们需要一种消耗它们的方法。 AWS使用术语“ targets来指代任何…

nodejs接收表单写入mysql_NodeJS提交表单存数据库(转)

姓名&#xff1a;性别&#xff1a;年龄&#xff1a;手机&#xff1a;$(#ok_btn).on(click,function(){var name $.trim($(#name).val()),sex $.trim($(#sex).val()),age $.trim($(#age).val()),tel $.trim($(#tel).val()),data {name : name,sex : sex,age : age,tel : te…

r语言 中断r的输入_R语言_004数据输入

现实的情况是&#xff0c;我们大部分遇到的都是表格数据&#xff0c;在R语言里面叫数据框&#xff0c;数据来源一般不可能我们自己在程序开始前手动录入&#xff0c;正常的逻辑是从外面读取现成的数据&#xff0c;再预处理、建模什么的。根据经验&#xff0c;现在的数据来源主要…

我的机器人现在无处可去。 无家可归。 无服务器。

我通常会关注各种网站-有关最新出版物&#xff0c;热门新优惠&#xff0c;限时游戏和竞赛等。 其中大多数不提供“干净”的通知系统&#xff0c;例如RSS feed。 因此&#xff0c;我经常不得不刮擦他们HTML才能达到我所需要的。 这意味着我经常需要运行一些自定义的字符串操作…

mysql怎么对比表结构_mysql查看表结构2种方式对比

C语言之带有返回值的函数带有返回值的函数 语法: 类型 函数名(参数列表){ 函数体; return 数据; } 例: int getSum(int num1,int num2){ int sum num1 num2 ...mysql 列转行&#xff0c;合并字段数据表: 列转行:利用max(case when then) max---聚合函数 取最大值 (case cours…

dubbo 消费者也要暴露端口吗_一文详细解读 Dubbo 中的 http 协议

(给ImportNew加星标&#xff0c;提高Java技能)转自&#xff1a;Kirito的技术分享&#xff0c;作者&#xff1a;kiritomoe太阳红彤彤&#xff0c;花儿五颜六色&#xff0c;各位读者朋友好&#xff0c;又来到了分享 Dubbo 知识点的时候了。说到 Dubbo 框架支持的协议&#xff0c;…

非一致性访存系统_Hibernate事实:访存策略的重要性

非一致性访存系统在使用ORM工具时&#xff0c;每个人都承认数据库设计和实体到表映射的重要性。 这些方面引起了很多关注&#xff0c;而诸如获取策略之类的事情可能只是推迟了。 我认为&#xff0c;不应将实体获取策略与实体映射设计分开&#xff0c;因为除非经过适当设计&…

应用新的JDK 11字符串方法

在“ 使用JDK 11的Java字符串上的新方法 ”和“ String&#xff03;repeat即将加入Java&#xff1f; ”&#xff0c;我讨论了JDK 11引入Java String的六个新方法。 可用的早期访问JDK 11构建已经包含了这些新方法&#xff0c;在这篇文章中&#xff0c;我将使用其中的一种早期访…

mysql 传统数据恢复_mysql 数据恢复实例

基于二进制日志数据恢复mysql数据恢复演练实例如何按需截取日志基于position好的截取--start-position--stop-positionmysqlbinlog --start-position219 --stop-position1272 /data/binlog/mysql-bin.000002 >/tmp/back.sql恢复删除库 mysql> drop database oldboy1;mysq…

mysql 强制读主库_laravel(lumen)配置读写分离后,强制读主(写)库数据库,解决主从延迟问题...

在Model里面加上下面这句&#xff0c;强制读主(写)库数据库&#xff0c;解决主从延迟问题。public static function boot(){//清空从连接,会自动使用主连接DB::connection()->setReadPdo(null);}-------------------------------------------------------------------------…

为什么需要切换到在线签署文档和合同

嘿&#xff0c;怪胎&#xff0c; 今天&#xff0c;我们为您带来一些不同。 无论您是开发人员&#xff0c;经理还是设计师&#xff0c;这都会提高您的生产力和效率。 对于公司和个人而言&#xff0c;良好地管理文书工作是强大基础的最重要部分之一。 将工作流程从纸质转移到数…

github怎么自动更新被人更新过的项目_GitHub 的这 8 个实用技巧,95%的人不知道...

知道的越多&#xff0c;不知道的就越多&#xff0c;业余的像一棵小草&#xff01;编辑&#xff1a;业余草来源&#xff1a;https://www.xttblog.com/?p49881、一秒钟把Github项目变成前端网站GitHub Pages大家可能都知道&#xff0c;常用的做法&#xff0c;是建立一个gh-pages…

mysql 未知列_mysql – ‘字段列表’连接中的未知列’..’

您在此查询中至少有两个问题.首先,当您使用反向标记来分隔标识符时,必须将表别名与列名称分开.verk.id -- WRONGverk.id -- CORRECT原因是SQL实际上允许您定义包含标点符号,空格等的列名称,如果您分隔列名称.这就是你似乎正在做的事情,请求一个名为verk.id的列verk.id -- ALSO …

java 注解 属性 类型_收藏!你一定要知道的Java8中的注解

全文共3002字&#xff0c;预计学习时长6分钟海中有大量的注解!JavaSE 1.5中首次引入了注解。Java注解的目的是允许程序员编写关于其程序的元数据。在OracleDocs中&#xff0c;注解的定义是:“注解是元数据的一种形式&#xff0c;它提供的数据与程序本身无关。”注解可以在代码的…

camel 多个 to_具有多个查询参数的Camel CXF服务

camel 多个 to出色的Apache Camel团队忙于解决查询中多个参数的处理问题&#xff0c;这是一种解决方法。 希望本文将在下一版本的Camel中不再使用。 &#xff08;目前&#xff0c;我使用2.7.5&#xff09; 问题 大于1的查询参数作为null值传递给Camel-CXF服务。 假设网址中有四…

select * from where 三个条件_VBA学习笔记70: Select语句基础

学习资源:《Excel VBA从入门到进阶》第72集 by兰色幻想 这节课来详细讲解Select语句。 Select 字段 from 表 where 条件 例:从sheet1中筛选全部数据。 * 表示全部字符,无条件可以省略where。 Select * from [sheet1$] 如果是对表中特定单元格区域进行查找,可以在[sheet1$]的…

使用Servlet和Bootstrap上传Ajax文件

介绍 在本教程中&#xff0c;我们将检查Ajax文件上传如何与Servlet一起使用。 同样&#xff0c;我们将用Bootstrap装饰表单并通过jQuery Ajax上传ajaxify文件。 实作 基本的servlet实现是相同的。 因此&#xff0c;我们需要做的第一件事是更新我们的web.xml文件并为我们的应用…

linux文件系统dentry_Linux文件系统(四)---三大缓冲区之inode缓冲区 (内存inode映像 )...

在文件系统中&#xff0c;有三大缓冲为了提升效率&#xff1a;inode缓冲区、dentry缓冲区、块缓冲。(内核&#xff1a;2.4.37)一、inode缓冲区为了加快对索引节点的索引&#xff0c;引入inode缓冲区&#xff0c;下面我们看Linux/fs/inode.c代码。inode缓冲区代码1、一些数据结构…

java 快死了_如果Java快死了,那么它肯定看起来非常健康

java 快死了Java快要死了的奇怪但流行的断言只能在没有证据的情况下提出&#xff0c;而不是因为它。 在酷孩子闲逛的论坛&#xff08;Hacker News&#xff0c;Reddit等&#xff09;中反复出现的偏见与Java语言背道而驰。 人们常常反复感叹 Java冗长而流行。 虽然我接受第一个描…

python函数调用时所提供的参数可以是变量吗_Python函数一章,关于变量参数调用(何时使用*)记录,pytho,章节,可变,的,什么,时候...

关于可变参数调用def bmi(*person):for list_person in person:for item in list_person:…这个&#xff0c;调用时&#xff0c;不需要带*bmi(list1,list2…)def bmi(*person):for item in person:…这个调用时&#xff0c;需要带*bmi(*list1&#xff0c;*list2)注&#xff1a;…