『MySQL 实战 45 讲』“order by” 是怎么工作的

news2024/11/26 22:28:32

“order by” 是怎么工作的

  1. 首先创建一个表
CREATE TABLE `t` ( 
	`id` int(11) NOT NULL, 
	`city` varchar(16) NOT NULL, 
	`name` varchar(16) NOT NULL, 
	`age` int(11) NOT NULL, 
	`addr` varchar(128) DEFAULT NULL, 
	PRIMARY KEY (`id`), 
	KEY `city` (`city`)
) ENGINE=InnoDB;

全字段排序

  1. city 字段上创建索引,然后执行下面语句
select city,name,age from t where city='杭州' order by name limit 1000 ;
  1. 通过 explain 结果会出 Extra 字段中,出现 Using filesort,表示需要排序,MySQL 会给每个线程分配一块内存用于排序,称为 sort_buffer
    在这里插入图片描述
  2. 上述语句执行流程如下
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/05312064b47d43b18a5e5ff5a538aa55.png
  • 初始化 sort_buffer,确定放入 name、city、age 这三个字段
  • 从索引 city 找到第一个满足 city='杭州’ 条件的主键 id,也就是图中的 ID_X
  • 到主键 id 索引取出整行,取 name、city、age 三个字段的值,存入 sort_buffer 中
  • 从索引 city 取下一个记录的主键 id
  • 重复步骤 3、4 直到 city 的值不满足查询条件为止,对应的主键 id 也就是图中的 ID_Y
  • 对 sort_buffer 中的数据按照字段 name 做快速排序
  • 按照排序结果取前 1000 行返回给客户端
  1. 其中,排序的时候可能会用到外部排序,就需要设置 sort_buffer_size,避免导致 sort_buffer 太小而不得不利用磁盘临时文件来辅助排序
  2. 确定排序语句是否使用了临时文件的方法
/* 打开optimizer_trace,只对本线程有效 */
SET optimizer_trace='enabled=on'; 

/* @a保存Innodb_rows_read的初始值 */
SELECT VARIABLE_VALUE INTO @a FROM  performance_schema.session_status WHERE variable_name = 'Innodb_rows_read';

/* 执行语句 */
SELECT city, NAME,age FROM t WHERE city='杭州' ORDER BY NAME LIMIT 1000; 

/* 查看 OPTIMIZER_TRACE 输出 */
SELECT * FROM `information_schema`.`OPTIMIZER_TRACE`\G

/* @b保存Innodb_rows_read的当前值 */
SELECT VARIABLE_VALUE INTO @b FROM performance_schema.session_status WHERE variable_name = 'Innodb_rows_read';

/* 计算Innodb_rows_read差值 */
SELECT @b-@a;
  • 其中,在 SELECT * FROM `information_schema`.`OPTIMIZER_TRACE`\G 的内容中如果出现 number_of_tmp_files,就表明用了临时表的份数(8.0 版本好像没看着)
    在这里插入图片描述
  1. 而 SELECT @b-@a; 代表的是查询前后获取的值的相减,得到的意思是整个过程扫描了多少行
  • 如果发现值和预期值多 1,就需要设置 internal_tmp_disk_storage_engine 属性为 MyISAM(默认 InnoDB),可能是因为查询 OPTIMIZER_TRACE 时,用到了临时表,所以会加 1

rowid 排序

  1. 全字段排序会把要返回的字段放到 sort_buffer 中,如果字段太多,就会分成多个临表
  2. 当排序单行太大,MySQL 会用另外一种算法,例如更改 max_length_for_sort_data 专门用于控制排序的行数据参数
SET max_length_for_sort_data = 16;
  1. city、name、age 这三个字段的定义总长度是 36 > 16,所以 sort_buffer 只会放入 排序的列主键 id
    在这里插入图片描述
  • 初始化 sort_buffer,确定放入两个字段,即 name 和 id
  • 从索引 city 找到第一个满足 city=‘杭州’ 条件的主键 id,也就是图中的 ID_X
  • 到主键 id 索引取出整行,取 name、id 这两个字段,存入 sort_buffer 中
  • 从索引 city 取下一个记录的主键 id
  • 重复步骤 3、4 直到不满足 city='杭州’条件为止,也就是图中的 ID_Y
  • 对 sort_buffer 中的数据按照字段 name 进行排序
  • 遍历排序结果,取前 1000 行,并按照 id 的值回到原表中取出 city、name 和 age 三个字段返回给客户端
    • 其中 “结果集” 是逻辑概念,实际上 MySQL 服务端从排序后的 sort_buffer 中依次取出 id,然后到原表查到 city、name 和 age 这三个字段的结果,不需要在服务端再耗费内存存储结果,是直接返回给客户端的
  1. 如果用刚刚的 确定临时文件的方法,会发现比以前多了一些值,就是因为要 id 去原表取值

联合索引与索引覆盖

  1. 对表的字段 city 和 name 的联合索引
alter table t add index city_user(city, name);
  1. 查询过程就变成下面这样
    在这里插入图片描述
  • 从索引 (city,name) 找到第一个满足 city='杭州’条件的主键 id
  • 到主键 id 索引取出整行,取 name、city、age 三个字段的值,作为结果集的一部分直接返回
  • 从索引 (city,name) 取下一个记录主键 id
  • 重复步骤 2、3,直到查到第 1000 条记录,或者是不满足 city=‘杭州’ 条件时循环结束
  1. 通过 explain 查询,就发现没有出现 Using filesort
  2. 如果想更快,就进行索引覆盖吧
alter table t add index city_user_age(city, name, age);
  1. 执行流程将会如下
    在这里插入图片描述
  • 从索引 (city,name,age) 找到第一个满足 city=‘杭州’ 条件的记录,取出其中的 city、name 和 age 这三个字段的值,作为结果集的一部分直接返回
  • 从索引 (city,name,age) 取下一个记录,同样取出这三个字段的值,作为结果集的一部分直接返回
  • 重复执行步骤 2,直到查到第 1000 条记录,或者是不满足 city=‘杭州’ 条件时循环结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/538552.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自己搭建go web 框架

思想base部分day1:封装gee封装context上下文封装tree路由树分组封装group与中间件封装文件解析封装封装错误处理 思想 web框架服务主要围绕着请求与响应来展开的 搭建一个web框架的核心思想 1 便捷添加响应路径与响应函数(base) 2 能够接收多种数据类型传入(上下文context) 3 构…

【Linux】Linux入门学习之常用命令五

介绍 这里是小编成长之路的历程,也是小编的学习之路。希望和各位大佬们一起成长! 以下为小编最喜欢的两句话: 要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡。 一个人为什么要努力&a…

支付系统设计五:对账系统设计01-总览

文章目录 前言一、对账系统构建二、执行流程三、获取支付渠道数据1.接口形式1.1 后台配置1.2 脚本编写1.2.1 模板1.2.2 解析脚本 2.FTP形式2.1 后台配置2.2 脚本编写2.2.1 模板2.2.2 解析脚本 四、获取支付平台数据五、数据比对1. 比对模型2. 比对器 总结 前言 从《支付系统设…

AE基础教程

一:粒子插件。 AEPR插件-Trapcode Suite V18.1.0 中文版 二:跟随手指特效。 1:空对象位置关键帧跟随手指。 2:发射粒子位置,按住Alt键,连接到空对象位置处。。 三:CtrI导入素材快捷键。 四&a…

Elasticsearch基础学习-常用查询和基本的JavaAPI操作ES

关于ES数据库的和核心倒排索引的介绍 一、Elasticsearch概述简介关于全文检索引擎关系型数据库的全文检索功能缺点全文检索的应用场景Elasticsearch 应用案例 二、Elasticsearch学习准备安装下载关于es检索的核心-倒排索引正向索引(forward index)倒排索…

辅助驾驶功能开发-功能规范篇(16)-2-领航辅助系统NAP-自动变道-1

书接上回 2.3.4.自动变道 当车辆处于导航引导模式NOA功能时(即车辆横向控制功能激活),且车速大于40km/h,驾驶员按下转向灯拨杆或系统判断当前有变道需要时,自动变道系统通过对车道线、自车道前方目标距离、邻近车道前后方目标距离等环境条件进行判断,在转向灯亮起3s后控…

看到这个数据库设计,我终于明白了我和其他软测人的差距

测试人员为什么要懂数据库设计? 更精准的掌握业务,针对接口测试、Web 测试,都是依照项目/产品需求进行用例设计,如果掌握数据库设计知识,能直接面对开发的数据表,更好、更精准的理解业务逻辑;有…

【滑动窗口】滑窗模板,在小小的算法题里滑呀滑呀滑

首先大家先喊出我们的口号:跟着模板搞,滑窗没烦恼! 一.什么是滑动窗口? 滑动窗口算法是双指针算法的一种特定化的算法模型,常用于在特定的条件下求最大或者最小的字符串,特定的数组,以及字符序列…

JAVA 可用的高性能docker镜像及如何使用?

目前docker hub上下载量很大的java、openjdk镜像都已经被弃用,不再维护,目前可用的java docker镜像有哪一些呢?哪一些镜像是主流的? 本文带有领略java可用的镜像资源、如何使用它们,如何构建springboot镜像? 1. 可用的java镜像 1.1. amazoncorretto 1.1.1. 什么是Corr…

环路详解:交换机环路产生的过程和原因图解

前言: 在了解环路之前得先了解交换机的工作原理,当然交换机的基本工作原理其实非常简单,只有“单播转发与泛洪转发”、“交换机MAC地址表”这两个!其他的如vlan,生成树等也是在此基础上增加的,弥补交换机基…

node笔记_koa框架的路由

文章目录 ⭐前言⭐koa 原生路由写法⭐引入 koa-router💖 安装koa-router💖 动态读取路径文件作为路由 ⭐结束 ⭐前言 大家好,我是yma16,本文介绍koa框架的路由。 往期文章 node_windows环境变量配置 node_npm发布包 linux_配置no…

[网络安全]DVWA之XSS(Reflected)攻击姿势及解题详析合集

[网络安全]DVWA之XSS(Reflected)攻击姿势及解题详析合集 XSS(Reflected)-low level源代码姿势 XSS(Reflected)-medium level源代码姿势1.双写绕过2.大小写绕过 XSS(Reflected)-high level源代码str_replace函数 姿势 XSS(Reflected)-Impossible level源代…

ssh正反隧道(代理msf对icmp穿透监听)

ssh正向隧道: 就是将本地端口映射到远程上,相当访问本地端口就是访问远程的端口 正向 访问本地对应的是远程的端口 ssh -fNCL 本地ip:本地port:远程ip:远程port 用户远程ip/域名 实例: ssh -fNCL 192.168.222.128:90:192…

HTML的表单

前后端交互过程: 表单在 Web 网页中用来给访问者填写信息采集客户端信息,使网页具有交互的功能,用户填写完提交后,表单的内容就从客户端的浏览器传送到服务器上,经过服务器上程序处理后,再将用户所需信息传…

人机大战?——带你玩转三子棋(C语言)

TOC 1、前言 在学习完数组之后,我们就可以自己来实现一个简单游戏—三子棋了! 为了确保程序的独立性:我们创建了一个源函数game.c 和test.c,一个头文件game.h test.c——测试游戏 game.c——游戏函数的实现 game.h——游戏函数…

Redis缓存数据库(三)

目录 一、概述 1、Redis架构 2、AKF 3、CAP原则 一、概述 1、Redis架构 Redis 有哪些架构模式?讲讲各自的特点 单机版 特点:简单 问题: 1、内存容量有限 2、处理能力有限 3、无法高可用。 主从复制 Redis 的复制(replic…

python绘制散点图|散点大小和颜色深浅由数值决定

python绘图系列文章目录 往期python绘图合集: python绘制简单的折线图 python读取excel中数据并绘制多子图多组图在一张画布上 python绘制带误差棒的柱状图 python绘制多子图并单独显示 python读取excel数据并绘制多y轴图像 python绘制柱状图并美化|不同颜色填充柱子 python随机…

【嵌入式系统应用开发】FPGA——HLS入门实践之led灯闪烁

目录 1 HLS1.1 HLS简介1.2 HLS与VHDL/Verilog1.3 HLS优点与局限 2 环境配置3 HLS实例——Led点亮3.1 工程创建3.2 添加文件3.3 C仿真与C综合3.4 创建Vivado工程3.5 导入HLS生成的IP核3.6 添加实验代码3.7 编译生成获取结果 总结 1 HLS 1.1 HLS简介 HLS(High Level Synthesis)…

十大排序算法(上)直接插入排序、希尔排序、直接选择排序、堆排序

🌈目录 1. 排序的概念2. 常见的排序算法3. 排序算法的实现3.1 插入排序3.1.1 直接插入排序3.1.2 希尔排序(缩小增量排序) 3.2 选择排序3.2.1 基本思想3.2.2 直接选择排序3.2.3 堆排序 1. 排序的概念 排序,就是使一串记录&#xf…

阿里通义千问_VS_讯飞星火

今天终于获得阿里通义千问大模型体验授权,第一时间来测试一下效果,使用申请手机号登录(地址:https://tongyi.aliyun.com)后,需要同意通义千问大模型体验规则,如下图所示: 同意之后就…