order by原理

打印 上一主题 下一主题

主题 1057|帖子 1057|积分 3175

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
前置知识

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

不能根据索引直接知道排序结果,就需要用到 sort buffer
排序的执行情况?

表T:id (primary key), city (key), name, age 等字段
  1. explain select city,name,age from T where city = 'gz' order by name;
  2. -- 走了索引(但是是非覆盖索引),需要排序,需要进行回表查询
  3. -- Using index condition; Using filesort
复制代码
这个 SQL语句可以知道,不能根据索引直接知道排序结果,所以需用到  sort buffer 排序
● 全字段排序 执行流程
初始化 sort buffer,确定此内存中需要存放的字段
到 city 字段索引上找到匹配的第一行
回表查询,把 city,name,age 存到  sort buffer 中
重复上述两步,直到不满足 where 条件(city 索引上找到一行不满足的数据)
对  sort buffer 中的数据排序
返回结果集给客户端
● rowid 排序执行流程
排序前,会检测放入 sort buffer 中的字段的长度,如果超过最大单行长度值(可调),那么就会只放rowid 和 需要排序的字段
  1. explain select city,name,age from T where city = 'gz' order by name;
  2. -- 走了索引(但是是非覆盖索引),需要排序,需要进行回表查询
  3. -- 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 条件

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王國慶

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表