偏向于业务的(MySQL)DBA或者业务的开发者来说,order by 排序是一个常见的业务功能,将结果根据指定的字段排序,满足前端展示的需求。然而排序操作也是经常出现慢查询排行榜的座上宾。本文将从原理和实际案例优化,order by 使用限制等几个方面来逐步了解order by 排序。
二 原理
在了解order by 排序的原理之前,强烈安利两篇关于排序算法的文章 《归并排序的实现》 《经典排序算法》。MySQL 支持两种排序算法,常规排序和优化,并且在MySQL 5.6版本中 针对order by limit M,N 做了特别的优化,这里列为第三种。
2.1 常规排序
a 从表t1中获取满足WHERE条件的记录
b 对于每条记录,将记录的主键+排序键(id,col2)取出放入sort buffer
c 如果sort buffer可以存放所有满足条件的(id,col2)对,则进行排序;否则sort buffer满后,进行排序并固化到临时文件中。(排序算法采用的是快速排序算法)
d 若排序中产生了临时文件,需要利用归并排序算法,保证临时文件中记录是有序的
e 循环执行上述过程,直到所有满足条件的记录全部参与排序
f 扫描排好序的(id,col2)对,并利用id去捞取SELECT需要返回的列(col1,col2,col3)
g 将获取的结果集返回给用户。
从上述流程来看,是否使用文件排序主要看sort buffer是否能容下需要排序的(id,col2)对,这个buffer的大小由sort_buffer_size参数控制。此外一次排序需要两次IO,一次是捞(id,col2),第二次是捞(col1,col2,col3),由于返回的结果集是按col2排序,因此id是乱序的,通过乱序的id去捞(col1,col2,col3)时会产生大量的随机IO。对于第二次MySQL本身一个优化,即在捞之前首先将id排序,并放入缓冲区,这个缓存区大小由参数read_rnd_buffer_size控制,然后有序去捞记录,将随机IO转为顺序IO。
2.2 优化排序
常规排序方式除了排序本身,还需要额外两次IO。优化的排序方式相对于常规排序,减少了第二次IO。主要区别在于,放入sort buffer不是(id,col2),而是(col1,col2,col3)。由于sort buffer中包含了查询需要的所有字段,因此排序完成后可以直接返回,无需二次捞数据。这种方式的代价在于,同样大小的sort buffer,能存放的(col1,col2,col3)数目要小于(id,col2),如果sort buffer不够大,可能导致需要写临时文件,造成额外的IO。当然MySQL提供了参数max_length_for_sort_data,只有当排序元组小于max_length_for_sort_data时,才能利用优化排序方式,否则只能用常规排序方式。
2.3 优先队列排序
为了得到最终的排序结果,无论怎样,我们都需要将所有满足条件的记录进行排序才能返回。那么相对于优化排序方式,是否还有优化空间呢?5.6版本针对Order by limit M,N语句,在空间层面做了优化,加入了一种新的排序方式:优先队列,这种方式采用堆排序实现。堆排序算法特征正好可以解limit M,N 这类排序的问题,虽然仍然需要所有元素参与排序,但是只需要M+N个元组的sort buffer空间即可,对于M,N很小的场景,基本不会因为sort buffer不够而导致需要临时文件进行归并排序的问题。对于升序,采用大顶堆,最终堆中的元素组成了最小的N个元素,对于降序,采用小顶堆,最终堆中的元素组成了最大的N的元素。
三 优化
通过上面的原理分析,我们知道排序的本质是通过一定的算法(耗费cpu 运算,内存,临时文件IO)将结果集变成有序的结果集。如何优化呢?答案是分两个方面利用索引的有序性(MySQL的B+ 树索引是默认从小到大递增排序)减少排序,最好的方式是直接不排序。
-
create table t1(
-
id int not null primary key ,
-
key_part1 int(10) not null,
-
key_part2 varchar(10) not null default '',
-
key_part3
-
key idx_kp1_kp2(key_part1,key_part2,key_part4),
-
key idx_kp3(id)
- ) engine=innodb default charset=utf8
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1142
183.71 KB下载数642
644.84 KB下载数2755
相关文章
发现更多好内容猜你喜欢
AI推送时光机【MySQL】order by 原理以及优化
数据库2024-04-02
MySQL中Order By索引的优化
数据库2024-04-02
MySQL中如何优化order by语句
数据库2023-01-12
mysql织梦索引优化之MySQL Order By索引优化
数据库2024-04-02
mysql order by 排序原理解析
数据库2024-04-02
MySQL order by与group by查询优化实现详解
数据库2024-04-02
如何进行MySQL中的order by 优化
数据库2024-04-02
如何在Mysql中优化order by语句
数据库2024-04-02
MySQL中如何优化Order By Rand()效率
数据库2024-04-02
MySQL 原理优化之Group By的优化技巧
数据库2022-08-14
MySQL中(JOIN/ORDER BY)语句的查询过程及优化方法
数据库2024-04-02
MySQL数据库ORDER BY优化是怎样的呢
数据库2024-04-02
MYSQL order by排序导致效率低小优化
数据库2024-04-02
MySQL 5.7 ORDER BY排序的优化是怎样的
数据库2024-04-02
MySQL 临时表的原理以及优化方法
数据库2022-08-22
详解MySQL中Order By排序和filesort排序的原理及实现
数据库2022-08-16
MySQL中order by排序语句的原理是什么
数据库2023-07-04
MySQL的索引原理以及查询优化详解
数据库2024-04-02
咦!没有更多了?去看看其它编程学习网 内容吧