我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MySQL order by与group by查询优化实现详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MySQL order by与group by查询优化实现详解

前言

order by满足两种情况,会使用 index 方式排序:

  • order by语句使用索引最左前列(最左匹配法则)
  • where子句和order by子句条件列组合满足最左匹配法则(where条件使用索引的最左前缀为常量)

下面给出几个实例来说明,如下所示我们创建表并为其创建组合索引(c1,c2,c3)。

CREATE TABLE `testc` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `c1` varchar(100) DEFAULT NULL,
  `c2` varchar(100) DEFAULT NULL,
  `c3` varchar(100) DEFAULT NULL,
  `c4` varchar(100) DEFAULT NULL,
  `c5` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `testc_c1_IDX` (`c1`,`c2`,`c3`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

where与order by满足最左匹配法则

# c1 c2满足最左匹配法则
explain select * from testc where c1='a1' order by c2
# 与上面等价
explain select * from testc where c1='a1' order by c2,c3

MySQL order by与group by查询优化实现详解

key_len标明查找用到了索引 c1,Extra中是Using index condition 没有同时出现using where ,表明 c2 索引用来读取数据而非执行查找动作。

mysql Innodb下的B+树本身就是多路平衡树,那么索引换句话就是排好序的快速查找数据结构。如果order by用到了索引且排序和索引次序一样,那么无疑效果是最好的。

中间断裂

如下所示,缺少了c2,order by不满足最左匹配法则。

explain select * from testc where c1='a1' order by c3

可以看到Extra中Using index condition; Using filesort说明虽然where可以用到索引(单独c1满足最左匹配),但是排序不满足,故而出现了filesort。

MySQL order by与group by查询优化实现详解

大哥不在

如下c1不在,那么很显然无论查找还是排序都用不到索引。

explain select * from testc where c2='a2' order by c3

这里Extra是Using where; Using filesort,说明通过where子句过滤结果,然后对结果进行文件排序。

MySQL order by与group by查询优化实现详解

范围失效

如下所示,中间c2是个范围搜索,那么其后索引将失效也就是order by c3无法与where连接满足最左匹配法则。

explain select * from testc where c1='a1' and c2 > 'a2' order by c3

如下图所示,这里type = range,ken_len表示用到了 c1,c2索引。Extra是Using index condition; Using filesort表示查询用到了索引但是无法利用索引完成的排序操作。

MySQL order by与group by查询优化实现详解

这种情况如何优化呢?order by c2,c3!这样就可以保证索引排序而不需要filesort。

explain select * from agriculture.testc where c1='a1' and c2  > 'a2' 
order by  c2,c3

MySQL order by与group by查询优化实现详解

order by 次序相反

如下所示,order by的次序没有与索引次序保持一致。这里Extra为Using index condition; Using filesort

explain select * from testc where c1='a1' order by c3,c2

MySQL order by与group by查询优化实现详解

覆盖索引

前面几个都是select *,这里查找索引列。

没有where,order by满足全值匹配,select查询的数据是索引列。

explain select c1 from testc order by c1, c2,c3

这里Extra中只有Using index;

MySQL order by与group by查询优化实现详解

没有where,order by 大哥丢失,select查询的数据是索引列。

explain select c1 from testc order by c2,c3

这里Extra中是Using index; Using filesort

MySQL order by与group by查询优化实现详解

这里Extra信息为Using where; Using index; Using filesort

explain select c1 from testc where c1='a1' order by c3,c2

MySQL order by与group by查询优化实现详解

filesort的两种算法

filesort有两种机制:双路排序和单路排序。双路排序简单来讲就是两次扫描磁盘,最终得到数据。单路排序则是只需要读取一次,也就是一次磁盘IO。

双路排序

MySQL4.1之前是使用双路排序,读取行指针和order by列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出(可以理解为从磁盘读取排序字段,在buffer进行排序,然后再从磁盘读取其他字段)。

取一批数据要进行两次磁盘IO,这是很耗时的。故而在MySQL4.1之后,出现了第二种改进的算法,也就是单路排序。

单路排序

从磁盘读取查询需要的所有列,按照order by列在buffer对它们进行排序,然后扫描排序后的列表进行输出。它的效率更快一点,避免了第二次读取数据,并且把随机IO变成了顺序IO。但是其会使用更多的空间,因为其缓存了数据在内存中。

单路的问题

可能取出的数据大小超过了sort_buffer的容量,导致每次只能取sort_buffer容量大小的数据进行排序(创建tmp文件,多路合并),排完再取sort_buffer容量大小…从而多次IO(可能比双路更多)。

可以尝试增大sort_buffer_size参数的设置或者max_length_for_sort_data参数的设置。

总结

order by时select * 是一个大忌,应该是查询需要的字段。

当query的字段大小总和小于max_length_for_sort_data而且排序字段不是text|blob类型时,会用改进后的算法–单路排序,否则使用双路排序。

两种算法的数据都有可能超出sort_buffer的容量,超出之后会创建tmp文件进行合并排序导致多次IO。尤其对于单路排序来说风险更大,所以需要适当调整sort_buffer的容量。

提高max_length_for_sort_data会增加使用单路排序算法的概率。但是如果设置的太高,数据总容量超过sort_buffer的概率就增大,明显症状是磁盘IO高,CPU使用率低。

group by

前面提到的规则针对group by均适用,group by 实质是先排序后分组,遵照索引建的最佳左前缀。当无法使用索引时,增大max_length_for_sort_data和sort_buffer参数的值。

需要注意的是where优先级高于having,能写在where限定的条件尽量不要通过having。

MySQL order by与group by查询优化实现详解

到此这篇关于MySQL order by与group by查询优化实现详解的文章就介绍到这了,更多相关MySQL order by与group by内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MySQL order by与group by查询优化实现详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MySQL Group by的优化详解

一个标准的 Group by 语句包含排序、分组、聚合函数,比如 select a,count(*) from t group by a ; 这个语句默认使用 a 进行排序。如果 a 列没有索引,那么就会创建临时表来统计 a和 count
2022-05-15

SQL汇总统计与GROUP BY过滤查询实现

目录1、汇总统计2、GROUT BY3、如何对分组统计的结果进行过滤4、如何对分组统计的结果进行排序5、介绍SELECT语句中各个子句的书写顺序6、上方用到的表1、汇总统计介绍几个聚集函数有多少名学生SELECT COUNT(*) FR
2023-01-05

mysql怎么使用left join和group by实现高效查询

这期内容当中小编将会给大家带来有关mysql怎么使用left join和group by实现高效查询,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。mysql高效查询mysql牺牲了group by来增加l
2023-06-15

MySQL分组查询获取每组最新的一条数据详解(group by)

目录业务场景:解决方案:group by id 方案验证:那怎么样才可以实现呢?使用 inner join 内连接,如下:总结业务场景:最近项目中迭代一个旧的功能,再原有的设计上进行功能拓展(因成本等原因,不考虑项目重构),其中设计到了这
MySQL分组查询获取每组最新的一条数据详解(group by)
2024-08-18

MySQLorderby与groupby查询优化实现详解

orderby子句尽量使用index方式排序(即usingindex),避免使用filesort方式排序(即usingfilesort)。Index方式效率高,它指MySQL扫描索引本身完成排序,filesort则效率低
2022-11-13

详解MySQL中Order By排序和filesort排序的原理及实现

目录1.Order By原理2.filesort排序算法3.优化排序1.Order By原理mysql的Order By操作用于排序,并且会有多种不同的排序算法,他们的性能都是不一样的。假设有一个表,建表的sql如下:CREATE T
2022-08-16

MySQL范围查询优化的场景实例详解

目录思考题范围查询-基础场景一: a = 1 and b = 2 and c = 3场景二: a > 1 and b = 2场景三:a > 1 and b = 2 and c > 3编程客栈场景四: a > 1 ORDER BY b场景五:
2022-06-13

mysql in索引慢查询优化实现步骤解析

这篇文章主要为大家介绍了mysql in慢查询优化实现步骤的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-20

编程热搜

目录