order by 是怎样工作的

MYSQL order by到底是如何工作的? 在你开发应用的时候,一定会经常碰到需要根据指定的字段排序来显示结果的需求。还是以我们前面举例用过的市民表为例,假设你要查询城市是“杭州”的所有人名字,并且按照姓名排序返回前个人的姓名、年龄。这个语句看上去逻辑很清晰,但是你了解它的执行流程吗?今天,我就和你聊聊这个语句是怎么执行的,以及有什么参数会影响执行的行为。 阅读详情

一图胜千言

rowid排序

排序的时候,只将 order by 后面排序字段以及记录主键放入到 sort buffer 中。比如 select a,b,c from t order by a desc,

只将字段a,表主键id 放入 sort buffer 中

全字段排序

排序的时候,将select sql中所有字段都放入到 sort buffer 中一起参与排序,无需根据rowid 再去主键索引上获取记录。

比如 select a,b,c from t order by a desc,只将 a,b,c 三个字段让如sort buffer中,如果表 t 还有字段 d,字段 d 是不会被放入 sort buffer 中

sort_buffer

属于 server层,MySQL 会给每个线程(也就是每一个 session)分配一块内存用于排序,称为 sort_buffer。可以使用 sort_buffer_size 进行设置。

max_length_for_sort_data

全字段排序的最大行数据,默认值是 1024 字节。

怎么做比较的,需要排序的数据字段的定义大小的和大于max_length_for_sort_data,就使用 “rowid排序”,反之使用“全字段排序”。

例如:select a,b,c from t order by a desc,a,b,c 数据类型都是 varchar(8) max_length_for_sort_data 配置的是 16

a,b,c 字段定义之和是24 大于 16 就使用“rowid排序”

需要说明的是,如果是 rowid 排序,在排序完成后需根据排好序的 rowid,去主键索引获取记录,也就是需要回表操作

举例一条 order by sql的执行流程

CREATE TABLE `t2` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_a` (`a`) ) ENGINE=InnoDB;

在表 t2 中插入数据 1000 条数据

for(int i=1; i<=1000; i++) { insert into t2(id, a, b) values(i, i%100, i); }

sql select a, b from t2 where a = 10 order by b;

这里假设使用的是“全字段排序”,并且需要排序的数据都可以放入 sort buffer 中。

执行流程如下

  1. 初始化 sort_buffer;
  2. 从索引 a 找到第一个满足 a=10 条件的主键 id;
  3. 到主键 id 索引取出整行,取 a, b 两个字段的值,存入 sort_buffer 中;
  4. 从索引 a 取下一个记录的主键 id;
  5. 重复步骤 3、4 直到 a 的值不满足查询条件为止;
  6. 对 sort_buffer 中的数据按照字段 b 做快速排序;
  7. 返回数据给客户端

有个疑问,从执行流程看,扫描行数应该是10行,为什么是 10行,因为sql执行的时候会踩中字段a的索引,符合a=10的记录只有10行,所以扫描行数是 10 行。但是通过观察慢日志,实际扫描行数却是 20 行,为什么??一直没搞明白。

如何验证 order by 是否使用了临时表

通过以sql命令,验证是否使用了临时表

/* 打开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;

下面图片中的信息是 查看 OPTIMIZER_TRACE 输出的

number_of_tmp_files 表示的是,排序过程中使用的临时文件数。内存放不下时,就需要使用外部排序,外部排序一般使用归并排序算法。

可以这么简单理解,MySQL 将需要排序的数据分成 312 份,每一份单独排序后存在这些临时文件中。然后把这 312 个有序文件再合并成一个有序的大文件。

如果 sort_buffer_size 超过了需要排序的数据量的大小,number_of_tmp_files 就是 0,表示排序可以直接在内存中完成。

否则就需要放在临时文件中排序。sort_buffer_size 越小,需要分成的份数越多,number_of_tmp_files 的值就越大。

filesort_priority_queue_optimization 这个部分的 chosen=true,就表示使用了优先队列排序算法

优先队列算法简单介绍

假设表 t 有 一万条记录,执行sql select a, b, c from t order by a asc limit 3 假设sql执行的时候选择了,rowid排序,并且使用的是优先队列排序算法

优先队列算法,就可以精确地只得到 3 个最小值,执行流程如下:

1:对于这 10000 个准备排序的 (R,rowid),先取前三行,构造成一个堆;

(对数据结构印象模糊的同学,可以先设想成这是一个由三个元素组成的数组)

2:取下一个行 (R’,rowid’),跟当前堆里面最大的 R 比较,如果 R’小于 R,把这个 (R,rowid) 从堆中去掉,换成 (R’,rowid’);

3:重复第 2 步,直到第 10000 个 (R’,rowid’) 完成比较。

通过优先队列排序找到最小的三个 R 值的行的过程。整个排序过程中,为了最快地拿到当前堆的最大值,总是保持最大值在堆顶,因此这是一个最大堆。

内存表排序

在内存表上进行排序,使用的是 rowid 排序。为什么不选择全字段排序,而选择 rowid 排序

如果使用 rowid 排序,执行流程是这样的

  • rowid排序的时候,将需要排序的字段 和 数据行的位置(数组中的下标)放入sort buffer 中。
  • 回表过程对于内存表来说就是根据 数据行的位置(数组中的下标),直接访问内存得到数据,根本不会导致多访问磁盘。
  • rowid 排序,可以一次性放入sort buffer中的数据就更多,避免创建临时文件或者减少临时文件的数量,

综上所述,内存临时表上进行排序会选择 rowid排序,参数 max_length_for_sort_data 对内存表的排序是起不到作用的

数组下标:memory引擎的表,数据是保存在数组中的,数据在数组中的排列顺序是数据的插入顺序

避坑指南:ROS2 Humble摄像头标定常见错误排查(从‘CALIBRATE’按钮不变绿到保存文件找不到) 本文详细解析了ROS2 Humble环境下摄像头标定的常见问题及解决方案,从CALIBRATE按钮不变绿到标定文件保存失败等疑难杂症。提供硬件准备、参数设置、实时诊断到结果验证的全流程指导,特别针对Ubuntu2204系统和usb_cam驱动的兼容性问题给出实用建议,帮助开发者高效完成内参标定。 阅读详情

相关推荐

【AWS】创建aws云服务器EC2实例

本文介绍了如何创建aws的EC2云服务器,并介绍了如何使用Xshell远程连接上云服务器

Marcos921的博客 2502

16 | “order by”是怎么工作的?

在你开发应用的时候,一定会经常碰到需要根据指定的字段排序来显示结果的需求。还是以我们前面举例用过的市民表为例,假设你要查询城市是“杭州”的所有人名字,并且按照姓名排序返回前1000个人的姓名、年龄。 假设这个表的部分定义是这样的: CREATE TABLE `t` ( `id` int(11) NOT NULL, `city` varchar(16) NOT NULL, `name` v...

weixin_34234829的博客 200

Vector CANoe VT2516A实战:从硬件连接到CAPL脚本的完整配置指南

本文详细介绍了Vector CANoe VT2516A板卡从硬件连接到CAPL脚本编写的完整配置指南。涵盖硬件接线原则、VT System配置避坑技巧、系统变量创建规范、可视化Panel设计、CAPL脚本调试及典型故障排查案例,帮助工程师快速掌握VT2516A板卡的应用实践,提升汽车电子测试效率。

weixin_30608503的博客 255

order by原理分析

日常开发中,我们经常会使用到order by,那你是否知道order by 的工作原理呢?order by的优化思路是怎样的呢?使用order by有哪些注意的问题呢?

Chenwen666的博客 429

手把手教你使用HFSS仿真高速差分过孔—上

高速数字电路设计中,信号完整性是一个非常重要的问题。为了使信号保持良好的传输特性,PCB板上的互联线一般都采用均匀传输线,使互联线保持特性阻抗一致性,减少信号反射。然而PCB板上的互联线很多时候避免不了换层的问题,这时候就必须使用过孔。过孔会导致阻抗不连续,进而造成反射,出现信号完整性问题。         当信号传输速率越高,信号前沿越短的时候,过孔引入的信号完整性问题越严重,需要对过孔进行优

a2447944219的博客 2万+

realsense D455深度相机+YOLO V5结合实现目标检测(一)

realsense D455深度相机+YOLO V5结合实现目标检测代码来源环境配置代码分析:1.如何用realsense在python下面调用的问题:2.对main_debug.py文件的分析:结束语 可以实现将D435,D455深度相机和yolo v5结合到一起,在识别物体的同时,还能测到物体相对与相机的距离。 说明一下为什么需要做这个事情?1.首先为什么需要用到realsense D455深度相机? 因为他是普通的相机还加了一个红外测距的东西,所以其他二维图像一样,能够得到三维世界在二维像素平面的投影

文一生 3万+

order by是如何工作的?

不经一番寒彻骨,怎得梅花扑鼻香 阅读这篇文章大概需要20分钟! 大家好前面我们了解了count(*)的一些实现方式。今天我们介绍一下order by的实现方式以及内部的涉及到的知识点。 常规排序 先准备一些案例,假设我们的表是这样的。 CREATE TABLE `t` ( `id` INT ( 11 ) NOT NULL, `city` VARCHAR ( 16 ) NOT NULL, `name` VARCHAR ( 16 ) NOT NULL, `age` INT ( 11 ) NOT N.

欢少的成长之路的博客 408

全志平台Sensor驱动移植实战:从点亮到调优的完整指南

本文详细介绍了在全志平台上进行Sensor驱动移植的全过程,从硬件引脚配置到软件参数调优,涵盖点亮、出图和调优三大阶段。重点解析了OV02B10传感器的I2C通信建立、上电时序调试和初始化参数配置等关键技术点,并提供了实用的调试技巧与问题排查指南,帮助开发者高效完成全志平台Sensor驱动移植工作。

weixin_28727975的博客 218

MySQL45讲 第十六讲 “order by”是怎么工作的?

在应用开发中,经常需要根据指定字段排序显示结果。本文以查询城市为 “杭州” 的市民信息并按姓名排序为例,深入探讨 MySQL 中 “order by” 语句的执行流程、不同算法以及相关优化策略,避免在开发中出现性能问题。

KELLENSHAW的博客 1917

【HOJ系列】HOJ判题机部署

【HOJ系列】HOJ判题机部署

随风浪仔的专栏 904

2025电赛嵌入式:K210教程-如何刷固件 如何烧录代码 全网唯一

本文介绍了K210开发板的固件刷写和开发环境搭建方法。主要内容包括:1)从Sipeed官网下载合适的MaixPy固件,根据需求选择完整版或精简版;2)使用k-flash等工具烧录固件,注意区分亚博和Sipeed开发板的固件版本;3)介绍了擦除闪存的两种模式(部分擦除和完全擦除)及其应用场景;4)搭建CanMV开发环境,通过MaixPy IDE连接开发板并进行程序调试。文章还提供了常见问题的解决方法,如串口驱动安装、固件兼容性检查等,为K210开发提供了完整的入门指南。

FJN110的博客 547

MySQL笔记 | 9.ORDER BY是如何工作的?

前言 每次业务功能中总有按时间排序,或者按其他字段排序的需求,一想到排序我们就会想到MySQL中的order by,那在使用的过程中,我们是否会存在不合理的使用导致查询的速度下降呢? 正文 为了避免全表查询,我们通常是在order by的字段上加上索引,这也是为什么我们需要在排序字段上加上对应的索引。 explain select t.passenger_uuid ,t.order_no from yy_order t order by t.order_no limit 1000; explain分析结果

小郭的博客 747

行为预测模型:Social LSTM与Graph Neural Networks

行为预测模型:Social LSTM与Graph Neural Networks ,人工智能,计算机视觉,大模型,AI,本文围绕行为预测模型Social LSTM与Graph Neural Networks展开,介绍了两者的基础概念、原理、应用场景,还对比了它们在优势、劣势和适用场景上的不同,最后给出了相应的代码示例。Social LSTM基于LSTM,通过社交池化层处理多智能体交互;图神经网络处理图结构数据,靠消息传递获取信息,二者各有侧重,适用于不同场景。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 15万+

“order by“是怎么工作的

文章目录16-"order by"是怎么工作的1. 全字段排序1.1 SQL查询语句的执行过程1.2 sort_buffer_size2 rowid排序2.1 MySQL处理排序的单行长度太大2.2 Rowid排序的执行流程3 全字段排序 VS rowid排序3.1 不需要排序3.2 优化执行流程4. 小结 16-"order by"是怎么工作的 假设表定义如下 CREATE TABLE `t` ( `id` int(11) NOT NULL, `city` varchar(16) NOT

weixin_36723038的博客 1042

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Order By 排序是如何工作的?

作者简介:大家好,我是码炫码哥,前中兴通讯、美团架构师,现任某互联网公司CTO,兼职码炫课堂主讲源码系列专题代表作:《jdk源码&多线程&高并发》,《深入tomcat源码解析》,《深入netty源码解析》,《深入dubbo源码解析》,《深入springboot源码解析》,《深入spring源码解析》,《深入redis源码解析》等联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬。

smart_an的专栏 817

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

“order by”是怎么工作的?

但这个算法有一个问题,就是如果查询要返回的字段很多的话,那么sort_buffer里面要放的字段数太多,这样内存里能够同时放下的行数很少,要分成很多个临时文件,排序的性能会很差。全字段排序定义:全字段排序通常是指在执行ORDER BY操作时,如果无法使用索引进行排序(例如,排序依据包含了未建立合适索引的列,或者排序涉及多个索引无法合并使用时),MySQL需要将满足条件的行的相关信息读入到sort_buffer中进行排序。新的算法放入sort_buffer的字段,只有要排序的列(即name字段)和主键id。

huangyujun9920123的博客 949

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

MySQL order by是怎么工作的

Extra 这个字段中的“Using filesort”表示的就是需要排序,MySQL 会给每个线程分配一块内存用于排序,称为 sort_buffer。满足 city='杭州’条件的行,是从 ID_X 到 ID_(X+N) 的这些记录。我们暂且把这个排序过程,称为全字段排序,执行流程的示意图如下所示,下一篇文章中我们还会用到这个排序。“按 name 排序”这个动作,可能在内存中完成,也可能需要使用外部排序,这取决于排序所需的内存和参数 sort_buffer_size。

loopnz的博客 139

【实战篇】“order by”是怎么工作的?

但这个算法有一个问题,就是如果查询要返回的字段很多的话,那么 sort_buffer 里面要放的字段数太多,这样内存里能够同时放下的行数很少,要分成很多个临时文件,排序的性能会很差。如果 MySQL 认为内存足够大,会优先选择全字段排序,把需要的字段都放到 sort_buffer 中,这样排序后就会直接从内存里面返回查询结果了,不用再回到原表去取数据。如果 sort_buffer_size 超过了需要排序的数据量的大小,number_of_tmp_files 就是 0,表示排序可以直接在内存中完成。

shenyongsi的博客 1296

mysql之order by工作原理

MySQL之order by工作原理

qq_41820066的博客 590

【MySQL】order by 的工作原理

Mysql学习之order by的工作原理

后端研发工程师Marion的博客 279

深度整理总结MySQL——Order By的工作原理

这篇文章是对知识内容进行整合加上自己的理解,文章内容来自于各种文章,书籍,工作号内容.下面的内容我会列举是在哪里看的,然后写一下我自己的理解和总结

左灯右行的爱情 1365

MySQL order by 工作原理

MySQL order by 工作原理: 一、MySQL是怎么进行排序? MySQL会为每个线程分配一个内存(sort_buffer)用于排序,内存大小为sort_buffer_size; 如果排序的数据量小于sort_buffer_size,排序会在内存中完成; 如果排序数据量很大,内存中无法存下这么多数据,会使用磁盘临时文件来辅助排序,也称外部排序; 在使用外部排序时,MySQL会分成好几份...

Fe_cow的博客 960

order by是怎么工作的?

中的 sql/orderbyDemo 部分将order by 的字段加到索引当中,查询耗时。根本原因是 利用了索引的有序性,不用进行额外的排序(Extra 中的 Using filesort)

trigger的博客 475

mysql 之order by工作流程

1.初始化sort_buffer 放入要排序的字段和主键ID 2.走索引找到满足条件的主键ID 再通过主键ID 取出排序字段和ID 放到sort_buffer中 从索引找到下一个满足条件的主键ID 3.重复2 直到不满足条件 4.对sort_buffer中的值按照排序字段排序 5.回到原表取出所有查询的字段返回。从结果我们可以看到 采用的是rowid排序 但我们发现了结果中的 number_of_tmp_size 的值竟让是0 难道不需要临时文件吗?表示需要用临时表 上面意思就是需要的内存表上排序。

Maisu的博客 117

16 | “order by” 是怎么工作的?

文章目录16 | “order by” 是怎么工作的?全字段排序rowid 排序小结上期问题时间 16 | “order by” 是怎么工作的? 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 `

sdaujsj1的博客 248

mysql limit工作原理及order by效率分析

mysql limit工作原理及order by效率分析 MySQL的limit m n工作原理就是先读取前面m+n条记录,然后抛弃前m条,读后面n条想要的,所以m越大,偏移量越大,性能就越差。 推荐分页查询方法: 1、尽量给出查询的大致范围 SELECT c1,c2,cn... FROM table WHERE id>=20000 LIMIT 10; 2、子查询法 SELECT c1,c2,cn... FROM table WHERE id>= ( SELECT id FROM ta

niuyan666的博客 508
上一篇: innodb存储引擎之:索引的数据结构
下一篇: group by 是怎样工作的
三易的博客
博客等级 码龄15年 42粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值