mysql oreder by的单路排序和双路排序

724 阅读3分钟

innodb存储引擎的排序分为两大类,索引排序和文件排序,索引排序效率肯定是优于文件排序的,所以请尽可能的使用索引排序。

如何去查看sql语句是利用了哪种排序方式

答案就在explain关键字,查看sql语句的执行计划,我们可以从mysql官网看到

  • If the Extra column of EXPLAIN output does not contain Using filesort, the index is used and a filesort is not performed.
  • If the Extra column of EXPLAIN output contains Using filesort, the index is not used and a filesort is performed. 意思就是如果‘Extra ’列没有包含‘Using filesort’,则使用的是索引排序,否则就是文件排序

使用的是索引排序 这种就是没有使用文件排序 使用的是文件排序 文件排序 当然下面才是这篇博客我想说的内容

文件排序的两种实现

在mysql中,文件排序在4.1版本之前使用双路排序,在4.1之后使用单路排序 双路排序 需要扫描两次磁盘,先从磁盘中读取排序字段和对应行号到buffer中,在buffer中进行排序后,再从磁盘中读取需要查询的字段 单路排序 将排序字段和所要查询的字段一起读取到buffer中,进行排序,直接返回给客户端

上面提到了buffer,排序缓冲池,我们通过可以查看默认大小

show variables like "%sort_buffer%"

我在网上也看到了一些博客帖子等,在sort_buffer_size不够时会如何处理,有人说仍会使用使用单路排序,也有人说当数据超出sort_buffer_size时重新使用双录排序。 首先无论使用哪一种方式,都可能发生超出sort_buffer_size的情况,这时会创建tmp文件进行文件合并导致多次io,超出sort_buffer_size大小的时候肯定是选择双路排序更优,但这只是一个猜想,下面我们进行验证。

验证究竟使用的哪种排序方式

一、开启优化器跟踪 SET OPTIMIZER_TRACE="enabled=on" 二、执行sql select * from tab_no_index order by name //没有索引 在这里插入图片描述

执行完sql之后,查看跟踪信息

SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE limit 30 \G;

当使用文件排序时,TRACE字段的这个json中会有‘’filesort_summary这个字段 在这里插入图片描述 等下介绍这个值的意思,我们在对一个大表进行排序,同样查看跟踪信息 在这里插入图片描述 诶,和上面的不一样了

sort_mode字段介绍

sort_mode值提供有关排序缓冲区中元组内容的信息,共有三种值

  1. <sort_key, rowid>:双路排序
  2. <sort_key, additional_fields>:单路排序
  3. <sort_key, packed_additional_fields>:单路排序,这种相比上面将查询字段进行了一个打包压缩

这是官网的原话 The sort_mode value provides information about the contents of tuples in the sort buffer:

<sort_key, rowid>: This indicates that sort buffer tuples are pairs that contain the sort key value and row ID of the original table row. Tuples are sorted by sort key value and the row ID is used to read the row from the table.

<sort_key, additional_fields>: This indicates that sort buffer tuples contain the sort key value and columns referenced by the query. Tuples are sorted by sort key value and column values are read directly from the tuple.

<sort_key, packed_additional_fields>: Like the previous variant, but the additional columns are packed tightly together instead of using a fixed-length encoding.

结论

在查询数据超出sort_buffer_size时,使用双路排序