mysql执行成本分析4

197 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

FileSort两种排序方式

 select * from test_index where name > '北' order by addr;

单路排序

将我们通过where筛序出的结果集,全部放入到sort buffer中,按照order by 的条件进行排序,最终直接返回数据集合。

缺点:所有字段全部放入sort buffer中占用空间

-- mysql 8.0.27 版本
            
            "filesort_summary": { -- 文件排序信息
              "memory_available": 262144, 
              "key_size": 61,
              "row_size": 230, 
              "max_rows_per_buffer": 106,
              "num_rows_estimate": 106,
              "num_rows_found": 93,
              "num_initial_chunks_spilled_to_disk": 0,
              "peak_memory_used": 33792,
              "sort_algorithm": "std::sort",
              "sort_mode": "<fixed_sort_key, packed_additional_fields>"
            } /* filesort_summary */
 
 
-- mysql 5.6 版本
            "filesort_summary": {
              "rows": 93,   -- 预计扫描行数
              "examined_rows": 106, -- 参与排序的行
              "number_of_tmp_files": 0,-- 使用临时文件的个数,这个值如果为0代表全部使用的sort_buffer内存排序,否则使用的磁盘文件排序
              "sort_buffer_size": 234112,-- 排序缓存的大小,单位Byte
              "sort_mode": "<sort_key, additional_fields>" -- 排序方式,这里用的单路排序
            } /* filesort_summary */

双路排序

将我们通过where筛序出的结果集当中的主键id(或许是伪列rowid)以及order by的字段放入sort buffer当中,按照order by 的条件进行排序,然后按照排序后的主键id(或许是伪列rowid)进行回表查询出满足所有条件的记录,最终直接返回数据集合。

优点:当sort buffer空间有限时适合使用,因为放入的字段少,占用空间小。

-- mysql 8.0.27 版本 效果等同同mysql版本的单路排序(已失效)
 
     "filesort_summary": {
              "memory_available": 262144,
              "key_size": 61,
              "row_size": 230,
              "max_rows_per_buffer": 106,
              "num_rows_estimate": 106,
              "num_rows_found": 93,
              "num_initial_chunks_spilled_to_disk": 0,
              "peak_memory_used": 33792,
              "sort_algorithm": "std::sort",
              "sort_mode": "<fixed_sort_key, packed_additional_fields>"
            }
 
-- mysql 5.6版本
 
           "filesort_summary": {
              "rows": 93,
              "examined_rows": 106,
              "number_of_tmp_files": 0,
              "sort_buffer_size": 72416,
              "sort_mode": "<sort_key, rowid>" -- 双路排序
            } /* filesort_summary */

选择依据

MySQL 通过比较系统变量 max_length_for_sort_data(mysql8.0默认4096字节,mysql5.6默认1024字节) 的大小和需要查询的字段总大小来判断使用哪种排序模式。

1.如果字段的总长度小于max_length_for_sort_data ,那么使用 单路排序模式。 2.如果字段的总长度大于max_length_for_sort_data ,那么使用 双路排序模式。 image.png

image.png

结束语

记得最后关闭trace工具哟!

set session optimizer_trace="enabled=off",end_markers_in_json=OFF;