欢迎光临散文网 会员登陆 & 注册

MySql 你知道 order by 是怎么回事吗? MySql全字段排序与 rowid 排序

2021-03-15 19:19 作者:早起的年轻人  | 我要投稿

1 前言

如下我这里有一张抽题记录表,部分建表语句如下:

目前我在这个表中保存了 4000 万左右的数句,如下我执行查询语句:



你知道这个过程 order by 是怎么操作的吗?



2 MySql 全字段排序

在这个 question_extracting 抽题表中 ,我们为 user_id 添加了普通索引,所在在执行上述这个查询时,会走索引查询,

在上述这个查询,MySql 需要对查询结果进行排序,MySQL 会给每个线程分配一 块内存用于排序,称为 sort_buffer。

对于上述这个查询,它的查询过程如下:


  • 第一步 初始化 sort_buffer 区域 ,确定放入 total_score、question_number 、create_time 字段

  • 第二步 从索引 user_id 中 找到第一个满足 user_id='760’ 条件的主键 id

  • 第三步 回表到主键 id 索引取出整行,取 total_score、question_number 、create_time 三个字段的值,存入 sort_buffer 中

  • 第四步 从索引 user_id 取下一个记录的主键 id

  • 然后重复 第三步 和 第四步 直到 user_id 的值不满足查询条件为止

  • 查询结束后,对 sort_buffer 中的数据按照字段 total_score 做快速排序

  • 最后 按照排序结果取前 1000 行返回给客户端



在上述的这个排序过程,我们可以称为 全字段排序 。

参数 sort_buffer_size ,MySQL 为排序开辟的内存(sort_buffer)的大小,如果将要排序的数据量小于 sort_buffer_size,排序就在内存中完成;如果排序数据量太大,内存放不下,就需要使用用磁盘临时文件辅助排序,可称为 外部排序 。

在外部排序中,MySQL 将需要排序的数据分成 N 份,使用参数 number_of_tmp_files 来表示,每一份单独排序后存在这些临时文件中,然后把这 N 个有序文件再合并成一个有序的大文件。

在内存排序中,number_of_tmp_files的值为0,在外部排序中,number_of_tmp_files的值大于0,sort_buffer_size 的值越小,需要排序的数据量就需要分成的份数越多,number_of_tmp_files的值就越大。


3 MySql rowid 排序

MySql rowid 排序应用于 当查询要返回的字段很多的时候,这种情况下,使用全字段排序,如果单行很大,排序的数据量也会很大,排序的性能会很差。

参数 max_length_for_sort_data,在 MySQL 中控制用于排序的行数据的长度,如果单行的长度超过这个值,MySQL的排序算法就会将全字段排序切换为 rowid 排序。

如在这个查询中,在rowid 排序中,只有要排序的列 total_score 和主键 id 会放入到 sort_buffer 中,它的查询过程如下:


  • 第一步 初始化 sort_buffer 区域 ,确定放入两个字段 total_score、id字段

  • 第二步 从索引 user_id 中 找到第一个满足 user_id='760’ 条件的主键 id

  • 第三步 回表到主键 id 索引取出整行,取 total_score、id两个字段的值,存入 sort_buffer 中

  • 第四步 从索引 user_id 取下一个记录的主键 id

  • 然后重复 第三步 和 第四步 直到 user_id 的值不满足查询条件为止

  • 查询结束后,对 sort_buffer 中的数据按照字段 total_score 做快速排序

  • 然后从 sort_buffer 中取出 排序好的 id ,依次回表查询获取前 1000行



对比全字段排序与 rowid 排序,rowid 排序要比 全字段排序多一次回表查询操作,所以 对于 InnoDB 表来说,rowid 排序会要求回表多造成磁盘读,因此不会被优先选择。

4 explain 命令

用 explain 命令来查看上述查询语句的执行情况

Extra 这个字段中的“Using filesort”表示的就是需要排序。



完毕

不局限于思维,不局限语言限制,才是编程的最高境界。


MySql 你知道 order by 是怎么回事吗? MySql全字段排序与 rowid 排序的评论 (共 条)

分享到微博请遵守国家法律