order by原理
  lLaz4t1Dsv4b 2023年11月01日 93 0

前置知识

Using filesort:表示需要用到 sort buffer 内存空间进行排序
sort buffer 是一块可调整的内存空间,如果需要排序的数据量太大而空间不够,将用到磁盘临时文件来排序,效率很低

什么情况下会用到 sort buffer 来排序?

不能根据索引直接知道排序结果,就需要用到 sort buffer

排序的执行情况?

表T:id (primary key), city (key), name, age 等字段

explain select city,name,age from T where city = 'gz' order by name;
-- 走了索引(但是是非覆盖索引),需要排序,需要进行回表查询
-- Using index condition; Using filesort

这个 SQL语句可以知道,不能根据索引直接知道排序结果,所以需用到 sort buffer 排序

● 全字段排序 执行流程
初始化 sort buffer,确定此内存中需要存放的字段
到 city 字段索引上找到匹配的第一行
回表查询,把 city,name,age 存到 sort buffer 中
重复上述两步,直到不满足 where 条件(city 索引上找到一行不满足的数据)
对 sort buffer 中的数据排序
返回结果集给客户端

● rowid 排序执行流程
排序前,会检测放入 sort buffer 中的字段的长度,如果超过最大单行长度值(可调),那么就会只放rowid 和 需要排序的字段

explain select city,name,age from T where city = 'gz' order by name;
-- 走了索引(但是是非覆盖索引),需要排序,需要进行回表查询
-- Using index condition; Using filesort

MySQL如果检测到 city,name,age 等字段超过了最大单行长度值,就会只把 id, name 等字段放入 sort buffer 中

执行流程
相比全字段排序,基本流程一致。存入 sort buffer 中的字段变少了,在排序完后,又要回表查询然后返回结果集。效率变低了
这个排序机制是为了保证尽可能的使用 sort buffer 内存排序,减少内存存放的数据行,那么存放的数据量就更多。从而降低/不适用磁盘临时文件排序

如何优化?

可以这样创建普通索引 (city, name)。那么执行上述 SQL 语句时,不会用到内存排序
执行流程
到 city 字段索引上找到匹配的第一行
回表查询,把 city,name,age 作为 结果集 的一部分直接返回
重复上述两步,直到不满足 where 条件

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: MySQL执行流程 下一篇: MySQL数据类型补充
  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  yThMa20bw7iV   2024年05月20日   58   0   0 MySQL
  pwciJmn0pWhj   2024年05月18日   56   0   0 MySQL
  WOljo6A3TCPl   2024年05月20日   49   0   0 MySQL
  8MfSLxyzjZA4   2024年05月20日   52   0   0 MySQL
  pwciJmn0pWhj   2024年05月17日   52   0   0 MySQL
  U6xQfOH75OE1   2024年05月17日   42   0   0 MySQL
  ijEHlwWobBkw   2024年05月17日   48   0   0 MySQL
  ijEHlwWobBkw   2024年05月17日   50   0   0 MySQL
  IS5q6TY5yQNJ   2024年05月17日   47   0   0 MySQL
lLaz4t1Dsv4b