在程序设计当中,我们很多场景下都会用 group by 关键字。比如在分页读取数据时,为了避免重复扫描记录,这就是必须要使用 group by 了。

比如我们使用如下 DDL 创建表:

CREATETABLE`user_info` (

`id` int(11)NOTNULLAUTO_INCREMENT COMMENT'主键ID',

`city` varchar(16)NOTNULLCOMMENT'城市',

`name`varchar(16)NOTNULLCOMMENT'姓名',

`age` int(11)NOTNULLCOMMENT'年龄',

`addr` varchar(128)DEFAULTNULLCOMMENT'地址',

PRIMARYKEY(`id`),

KEY`city` (`city`)

) ENGINE=InnoDB DEFAULTCHARSET=utf8

并且我们会执行如下查询语句

SELECTcity,`name`,ageFROMuser_infoWHEREcity='上海'ORDERBY`name` LIMIT 1000;

全字段排序

因为上面的建表语句已经在 city 字段上面创建索引了,当我们使用 EXPLAIN 命令时,会有如下结果:

上面 Extra 字段中的 “Using filesort” 表示的就是需要排序,MySQL 会为每个线程分配一块内存用于排序,成为 sort_buffer。下面我们看一下 index(city) 的结构示意图。

执行流程如下:

初始化 sort_buffer,确定放入 city name age 这 3 个字段;

从 city 索引中获取到***个 city='上海' 的记录,也就是 id_x;

到主键索引中获取对应的记录,并取出 name city age 的值放入 sort_buffer;

取下一条符合条件的记录,重复 3 4 的操作,直至不符合条件为止;

对 sort_buffer 中的数据按照 name 做快速排序;

取出前 1000 条数据并返回。

我们暂时叫这种排序过程为“全字段排序”,如下所示:

图中的“按 name 排序” 可能在内存中,也可能使用磁盘文件排序,这取决与排序所需要的内存和 sort_buffer_size 。sort_buffer_size 就是 MySQL 为排序开辟的内存大小,当所需内存小于 sort_buffer_size 时,就直接在内存中完成排序,如果所需要的内存 大于 sort_buffer_size ,就需要额外的磁盘空间辅助排序。

rowid 排序

上面的算法在数据量比较大的时候,可能会出现一些问题。因为在排序的时候,存放了所有的返回字段,增加了 排序空间 (sort_buffer)的压力。

SETmax_length_for_sort_data=16;

max_length_for_sort_data 是MySQL 限制排序行大小的参数。意思是,如果排序行大小超过了这个值,就会另选排序算法。上面 name city age 3 个字段的大小为 36,大于 16 ,在新的算法中将只有 name (排序字段) 和id 参与 sort_buffer 中的排序。过程如下

初始化 sort_buffer,确定放入 name id 这 2 个字段;

从 city 索引中获取到***个 city='上海' 的记录,也就是 id_x;

到主键索引中获取对应的记录,并取出 name id 的值放入 sort_buffer;

取下一条符合条件的记录,重复 3 4 的操作,直至不符合条件为止;

对 sort_buffer 中的数据按照 name 做快速排序;

取出前 1000 条数据,然后根据 id 取出对应记录的 name city age 3 个字段并返回结果。

这种排序过程,我们称为 rowid 排序,过程如下所示:

全字段排序 VS rowid 排序

从上面 2 个流程看来,如果内存足够时,MySQL 会让返回值中所有字段存放在排序空间。当MySQL 内存过小时,才会考虑使用rowid 排序。但是从上面的流程看来,rowid 排序在返回结果前,还会再一次的回表。因此MySQL 认为内存充足的时候,会优先采用 全字段排序。

上面的场景是:city 字段过滤后,name 字段不是有序的。其实我们可以通过联合索引来规避掉 name 字段的排序。

altertableuser_infoaddindexidx_city_user(city,name);

下面我们看一下联合索引的示意图:

从上面流程图可以看出,当我们取出 city='上海' 的记录时,name的字段也是有序的。过程如下

从 (city, name)索引中获取到***个 city='上海' 的记录 id_x;

到主键索引中获取对应的记录,并取出 name city age 的值作为结果集的一部分直接返回;

取下一条符合条件的记录,重复 2 3 的操作,直至不符合条件或者达到 1000 条为止;

从联合索引看来,我们是可以不用排序操作了,那么我们是否可以直接通过 索引就直接返回结果呢?也就是不要回表操作。答案是有的,那就是覆盖索引。

altertableuser_infoaddindexidx_city_user_age(city,name, age);

当执行查询语句时,不仅 name 中的字段是有序的,并且 索引中已经包含了结果集中的所有字段,过程如下:

从 (city, name,age)索引中获取到***个 city='上海' 的记录,并取出 name city age 的值作为结果集的一部分直接返回;

取下一条符合条件的记录,重复 1 2 的操作,直至不符合条件或者达到 1000 条为止;

【编辑推荐】

【责任编辑:庞桂玉 TEL:(010)68476606】

点赞 0

mysql的原理图解_MySQL排序工作原理相关推荐

  1. 计算机网络交换机原理,计算机网络__交换机工作原理

    计算机网络交换机工作原理 在前面了解到根据交换机在OSI参考模型中工作的协议层不同,将交换机分为二层交换机.三层交换机.四层交换机.交换机工作的协议层不同,其工作原理也不相同.下面我们将介绍各层交换机 ...

  2. 微机计算机系统结构原理,计算机系统组成及工作原理题目

    计算机系统组成及工作原理计算机系统组成及工作原理 1 计算机系统一般有 硬件 和 软件 两大系统组成 2 微型计算机系统结构由运算器 控制器 存储器 输入设备 输出设备五大部分组成 3 微型计算机的运 ...

  3. 计算机网络中的网桥,一个动画看懂网络原理之网桥的工作原理

    一个动画看懂网络原理之网桥的工作原理 一.网桥是干什么的 网桥工作在OSI参考模型数据链路层的两端口或多端口二层网络设备,是用来连接不同网段的存储转发设备.使用网桥能扩展网络的距离或范围,还可以提高网 ...

  4. 时钟服务器工作原理,NTP时间服务器工作原理

    文章目录 [隐藏] NTP简介 NTP工作原理 NTP工作模式 NTP简介 NTP(Network Time Protocol, 网络时间协议)是由RFC 1305定义的时间同步协议,用来在分布式时间 ...

  5. 图解LVS的工作原理

    LVS详解 LVS简介 LVS特点: LVS常见术语 LVS工作原理 NAT模式 DR模式 内核参数详解 arp_ignore arp_announce TUN工作模式 full-nat模式 LVS调 ...

  6. 史上最全!图解浏览器的工作原理

    可能每一个前端工程师都想要理解浏览器的工作原理. 我们希望知道从在浏览器地址栏中输入 url 到页面展现的短短几秒内浏览器究竟做了什么: 我们希望了解平时常常听说的各种代码优化方案是究竟为什么能起到优 ...

  7. 图解WebGLThree.js工作原理【转】

    原文地址:https://www.cnblogs.com/wanbo/p/6754066.html 一.我们讲什么? 我们讲两个东西: 1.WebGL背后的工作原理是什么? 2.以Three.js为例 ...

  8. 图解WebGLThree.js工作原理

    "哥,你又来啦?" "是啊,我随便逛逛." "别介啊--给我20分钟,成不?" "5分钟吧,我很忙的." "不 ...

  9. 频谱仪使用方法图解_安全继电器工作原理、接线图、使用方法图解

     专享技术资料直通车,零基础轻松学PLC 所谓"安全继电器"是由数个继电器与电路组合而成,为的是要能互补彼此的异常缺陷,达到正确且低误动作的继电器完整功能,使其失误和失效值愈低,安 ...

最新文章

  1. CVPR2020中关于3D点云分割
  2. 一文入门 Python 数据分析库 Pandas
  3. OpenLdap 相关命令
  4. Tensorflow源码解析3 -- TensorFlow核心对象 - Graph
  5. boost::system::errc相关的测试程序
  6. 微型计算机启天A5000-B124说明,微型计算机原理及应用知识点总结
  7. 5月TIOBE编程榜,Java、PHP降级,C#再度上升!
  8. 计算机安全模型研究与应用,软件哨兵安全动态检测模型的研究与实现-计算机应用研究.PDF...
  9. web程序入门五(http无状态)
  10. oracle undo段的作用,Oracle数据库中Undo数据段的作用及类型
  11. ASP.NET基于donetCHARTING的自动报表
  12. 《Java 就业培训教程》
  13. 修改+首选+dns服务器地址,首选dns服务器地址怎么设置
  14. python可以做回归分析吗_使用python进行回归分析
  15. python基础语法大全
  16. 充电桩检测设备TK4860E交流充电桩检定装置
  17. 【软件教程】解决kali无法和windows实现复制黏贴互通
  18. 关于解决文件夹变成*.EXE可执行文件的问题
  19. 如何测试 tpc-c
  20. Linpack测试环境的搭建

热门文章

  1. Linux环境进程间通信---信号(下)
  2. NTP时间服务器安装
  3. dojo Quick Start/dojo入门手册--开始使用dojo.js
  4. 温昱谈架构和框架(Framework)的区别
  5. 不要为框架作过多的假设
  6. oracle expdp自动导出数据,Oracle expdp数据泵远程导出
  7. Python+Django+Nginx+Uwsgi 详细部署过程(爬坑过程,可以了解各个软件的执行流程,看过)
  8. python实现redis分布式锁
  9. 阿里P8架构师谈:阿里双11秒杀系统如何设计?
  10. 云上如何做冷热数据分离