杏彩平台出租与MySQL order by

一 简介

偏向于业务的 (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。杏彩平台出租[企俄:2152876294] 网址diguaym.com

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 的元素。

三 优化

猜你喜欢

转载自blog.51cto.com/13932267/2162272