暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

mysql的排序方式有3种

原创 傻子dba 2020-07-29
3312

mysql的排序方式有3种:

< sort_key, rowid > 对应的是MySQL 4.1之前的"原始排序模式"
< sort_key, additional_fields > 对应的是MySQL 4.1以后引入的"修改后排序模式"
< sort_key, packed_additional_fields > 是MySQL 5.7.3以后引入的进一步优化的"打包数据排序模式"

  1. 原始排序模式:
    根据索引或者全表扫描,按照过滤条件获得需要查询的排序字段值和row ID;
    将要排序字段值和row ID组成键值对,存入sort buffer中;
    如果sort buffer内存大于这些键值对的内存,就不需要创建临时文件了。否则,每次sort buffer填满以后,需要直接用qsort(快速排序算法)在内存中排好序,并写到临时文件中;
    重复上述步骤,直到所有的行数据都正常读取了完成;
    用到了临时文件的,需要利用磁盘外部排序,将row id写入到结果文件中;
    根据结果文件中的row ID按序读取用户需要返回的数据。由于row ID不是顺序的,导致回表时是随机IO,为了进一步优化性能(变成顺序IO),MySQL会读一批row ID,并将读到的数据按排序字段顺序插入缓存区中(内存大小read_rnd_buffer_size)。

  2. 修改后排序模式:
    根据索引或者全表扫描,按照过滤条件获得需要查询的数据;
    将要排序的列值和用户需要返回的字段组成键值对,存入sort buffer中;
    如果sort buffer内存大于这些键值对的内存,就不需要创建临时文件了。否则,每次sort buffer填满以后,需要直接用qsort(快速排序算法)在内存中排好序,并写到临时文件中;
    重复上述步骤,直到所有的行数据都正常读取了完成;
    用到了临时文件的,需要利用磁盘外部排序,将排序后的数据写入到结果文件中;
    直接从结果文件中返回用户需要的字段数据,而不是根据row ID再次回表查询。

  3. 打包数据排序模式:
    第三种排序模式的改进仅仅在于将char和varchar字段存到sort buffer中时,更加紧缩。
    在之前的两种模式中,存储了“yes”3个字符的定义为VARCHAR(255)的列会在内存中申请255个字符内存空间,但是5.7.3改进后,只需要存储2个字节的字段长度和3个字符内存空间(用于保存”yes”这三个字符)就够了,内存空间整整压缩了50多倍,可以让更多的键值对保存在sort buffer中。
    我们这个数据库的版本是5.6,所以无法用到第三种排序方式,那么它是怎么选择第二种还是第一种的排序方式呢?
    MySQL给用户提供了一个max_length_for_sort_data的参数。当“排序的键值对大小” >max_length_for_sort_data时,MySQL认为磁盘外部排序的IO效率不如回表的效率,会选择第一种排序模式;反之,会选择第二种不回表的模式。
    我们当前数据库的max_length_for_sort_data大小为:

mysql> show variables like ‘%max_length_for_sort_data%’;
±-------------------------±------+
| Variable_name | Value |
±-------------------------±------+
| max_length_for_sort_data | 1024 |
±-------------------------±------+
1 row in set (0.00 sec)

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论