专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
51好读  ›  专栏  ›  ImportNew

面试官:聊聊 order by

ImportNew  · 公众号  · Java  · 2024-04-25 07:35

正文

请到「今天看啥」查看全文



解释下这里使用磁盘临时文件来进行辅助排序的含义,外部排序常用的排序算法是多路归并排序算法,具体步骤如下:


  • 到主键 id 索引树上查找到对应的整行数据后,取 city、username、age 三个字段的值,存入 sort_buffer 中,能存多少是多少,当 sort_buffer 快要满时,就对 sort_buffer 中的数据进行排序,排完后,把数据临时放到磁盘的一个小文件中,然后清空 sort_buffer(这样的话,一个很大的数据,就会被分成若干个临时磁盘文件)
  • 继续回到主键 id 索引树取数据,重复上一步,直到取出所有满足条件的数据
  • 最后,归并已经有序的若干个临时磁盘文件,形成一个完整的有序大文件


7. 按照排序结果取前 1000 行返回给客户端


可以看出,整个排序过程,我们要查询的 city、username、age 全都参与了,所以,暂且把这个排序过程,称为全字段排序

整条语句的执行流程的示意图如下所示:



针对上面利用磁盘临时文件进行辅助排序的过程,不知道大家会不会有个很自然的想法:sort_buffer 内存放不下,需要用到临时磁盘文件,磁盘文件越多,排序效率显然就会越低下。那为什么还要把排序不相关的字段 city、username 放到 sort_buffer 中呢?只存放排序相关的 age 字段,这样划分的磁盘文件不就相对变少了嘛~


这就是 rowid 排序 👇


rowid 排序


rowid 排序,听名字大概就能理解,就是,只把需要用于排序的字段和对应的主键 id,放到 sort_buffer 中。


那怎么确定走的是全字段排序还是 rowid 排序呢?


实际上有个参数控制的。这个参数就是 max_length_for_sort_data,是 MySQL 中专门控制用于排序的行数据的长度的一个参数。它的意思是,如果单行的长度超过这个值,MySQL 就认为单行太大(那么数据量肯定就越大,sort_buffer 可能不够用),不能再像之前那样把所有 select 的字段都存进 sort_buffer 了,要换一个算法,只存排序相关的字段


show variables like 'max_length_for_sort_data';

  


可以看到,max_length_for_sort_data 的默认值是 1024。


可以通过下面这行命令进行修改


SET max_length_for_sort_data = 16;

  

表中我们定义的这三个字段 city、username、age 的总长度是 36,我把 max_length_for_sort_data 设置为 16,显然,单行的长度已经超过这个值了,排序算法应该由全字段排序转成了 rowid 排序。







请到「今天看啥」查看全文