MySQL中order by是怎么工作的?

news2024/11/20 10:42:22

图片

在如上图中所示的explain的执行结果中,Extra字段中的“Using filesort”表示的就是需要排序,MySQL会给每个线程分配一块内存用于排序,称为sort_buffer。

图片

索引city如上图所示

上述语句的执行流程如下:

1、初始化sort_buffer,放入name  city  age这三个字段;

2、从索引city中找到第一个满足city='杭州'的主键id,也就是上图中的ID_X;

3、到主键id索引取出整行,取name  city  age三个字段的值,放入sort_buffer中;

4、从索引city取下一个记录的主键id;

5、重复步骤3、4直到city值不满足查询条件为止,即上图中的ID_Y;

6、对sort_buffer中的数据按照字段name做快速排序;

7、按照排序结果取前1000行返回给客户端;

上述过程可称之为“全字段排序”

“按name排序”这个动作,可能在内存中完成,也可能需要使用外部排序,这取决于排序所需的内存和参数sort_buffer_size。sort_buffer_size是MySQL为排序开辟的内存(sort_buffer)的大小。如果要排序的数据量小于sort_buffer_size,排序在内存中完成,否则,内存放不下,不得不利用磁盘临时文件辅助排序,称为外部排序,外部排序一般使用归并排序算法。

rowid排序

max_length_for_sort_data参数,是MySQL中专门控制用于排序的行数据长度的一个参数,含意是:如果需要取出来的单行数据的长度超过这个值,MySQL就认为单行太大,要换一个算法。假设city  name  age三个字段的定义总长度是36,把max_length_for_sort_data设置为16,则执行过程变为:

1、初始化sort_buffer,确定放入两个字段,即name和id;

2、从索引city找到第一个满足city='杭州’条件的主键id,也就是图中的ID_X;

3、到主键id索引取出整行,取name、id这两个字段,存入sort_buffer中;

4、从索引city取下一个记录的主键id;

5、重复步骤3、4直到不满足city='杭州’条件为止,也就是图中的ID_Y;

6、对sort_buffer中的数据按照字段name进行排序;

7、遍历排序结果,取前1000行,并按照id的值回到原表中取出city、name和age三个字段返回给客户端。

上述流程称之为rowid排序。

全字段排序 VS rowid排序:

综上可得出MySQL的一个设计思想:如果内存足够,就多利用内存,采取全字段排序,尽量减少磁盘访问。

其实,并不是所有的order by语句,都需要排序操作的。比如,如果创建一个city和name的联合索引。

alter table t add index city_user(city, name);

则执行流程变为:

1、从索引(city,name)找到第一个满足city='杭州’条件的主键id;

2、到主键id索引取出整行,取name、city、age三个字段的值,作为结果集的一部分直接返回;

3、从索引(city,name)取下一个记录主键id;

4、重复步骤2、3,直到查到第1000条记录,或者是不满足city='杭州’条件时循环结束。

图片

可以看到Extra字段中没有Using filesort了,也就是不需要排序了。

更进一步优化,还可以采用覆盖索引,即索引上的信息足够满足查询请求,不需要再回到主键索引上去取数据。

alter table t add index city_user_age(city, name, age);

则执行流程变为:

1、从索引(city,name,age)找到第一个满足city='杭州’条件的记录,取出其中的city、name和age这三个字段的值,作为结果集的一部分直接返回;

2、从索引(city,name,age)取下一个记录,同样取出这三个字段的值,作为结果集的一部分直接返回;

3、重复执行步骤2,直到查到第1000条记录,或者是不满足city='杭州’条件时循环结束。

图片

可以看到,Extra里面多了“Using index”,表示的就是使用了覆盖索引,性能上会快很多。

正文止。

感兴趣的朋友,欢迎关注我的公众号哈,公众号上已经集成了AI大模型,大家可以过来聊天、问问题了

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

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

相关文章

【AIGC-文本/图片生成视频系列-8】Align your Latents: 基于潜在扩散模型的高分辨率视频合成

目录 一. 项目概述与贡献 二. 方法详解 三. 应用总览 四. 个性化视频生成 五. 实时卷积合成 六. 更多结果 七. 论文 八. 个人思考 AI生成高分辨率视频一直是一个挑战。 今天讲解一篇潜在扩散模型(LDM)用于高分辨率、时间一致且多样化的视频生成…

JVM加载class文件的原理机制

1、JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从“Hello World ”开始的,然后会写个复杂点class ,然后再找一些开源框架,比如Spring ,Hibernate 等等,再然后就开发…

leaflet学习笔记-带有方位角信息的圆的绘制(七)

前言 项目中有一个需求,就是需要绘制一个圆,并且绘制的时候还要设置方位角,最后返回圆的坐标集合和方位角。本功能使用Leaflet-GeomanTurf.jsleaflet实现。 方位角简介 在陆地导航中,方位角通常表示为 alpha、α,并定…

java中解码和编码出现乱码原因

一、UTF-8和GBK编码方式 如果采用的是UTF-8的编码方式,那么1个英文字母 占 1个字节,1个中文占3个字节如果采用GBK的编码方式,那么1个英文字母 占 1个字节,1个中文占2个字节 二、idea和eclipse的默认编码方式 其实idea和eclipse的…

力扣题解24. 两两交换链表中的节点(图解递归和双指针)

24. 两两交换链表中的节点 题目描述: 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入&…

使用Pygame显示文字的示例代码

import pygame import syspygame.init()# 设置窗口尺寸 win_size (800, 600) screen pygame.display.set_mode(win_size) pygame.display.set_caption("文字显示示例")# 设置字体和文字内容 font pygame.font.SysFont(None, 48) # 使用系统默认字体,字…

第十一章 Cookie

第十一章 Cookie 1.什么是Cookie2.Cookie的创建3.Cookie的获取4.Cookie值的修改5.谷歌浏览器和火狐浏览器如何查看Cookie6.Cookie的存活设置7.Cookie的path属性8.Cookie练习之免用户名登入 1.什么是Cookie 2.Cookie的创建 下面我看看如何创建Cookie,如何让客户端保…

极客时间-读多写少型缓存设计

背景 内容是极客时间-徐长龙老师的高并发系统实战课的个人学习笔记,欢迎大家学习!https://time.geekbang.org/column/article/596644 总览内容如下: 缓存性价比 一般来说,只有热点数据放到缓存才更有价值 数据量查询频率命中…

67.网游逆向分析与插件开发-角色数据的获取-分析角色数据基址

内容参考于:易道云信息技术研究院VIP课 上一个内容:角色类的数据分析与C还原-CSDN博客 基址这个东西说好找也好找,说不好找是真找不着,但就根据一个原则,就是确认这个东西有基址还是没基址,为什么会有没基…

STM32--基于STM32F103的MAX30102心率血氧测量

本文介绍基于STM32F103ZET6MAX30102心率血氧测量0.96寸OLED(7针)显示(完整程序代码见文末链接) 一、简介 MAX30102是一个集成的脉搏血氧仪和心率监测仪生物传感器的模块。它集成了一个红光LED和一个红外光LED、光电检测器、光器…

移动通信原理与关键技术学习之信道编解码(5)

先回顾调制的过程:调制就是对信号源的信息进行处理加到载波上,使其变为适合于信道传输的形式的过程,就是使载波随信号而改变的技术。 1.什么是IQ调制? 答:将数据分为两路,分别进行载波调制,两…

Camunda Sub Process

一:内嵌子流程 repositoryService.createDeployment().name("内嵌子流程").addClasspathResource("bpmn/embed_sub_process.bpmn").deploy(); identityService.setAuthenticatedUserId("huihui"); ProcessInstance processInstance …

教你三招该如何制作家具样本册

​随着生活品质的提高,人们对家居装饰的要求也越来越高。家具作为家居装饰的重要组成部分,其选择和搭配也显得尤为重要。为了更好地展示家具的特点和风格,制作家具样本册成为了许多人的选择。那么,如何制作一份精美的家具样本册呢…

Day31 贪心算法 part01 理论基础 455.分发饼干 376.摆动序列 53.最大子序和

贪心算法 part01 理论基础 455.分发饼干 376.摆动序列 53.最大子序和 理论基础(转载自代码随想录) 什么是贪心 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 这么说有点抽象,来举一个例子: 例如&#…

CMake入门教程【实战篇】使用Boost库

文章目录 安装 Boost 库CMake中使用Boost库时安装 Boost 库 下载地址 https://www.boost.org/users/download/ 下载版本 选择二进制版本或者源码 二进制版本直接安装即可 源码版本编译->安装 解压到本地目录,如e:/dev/。运行E:\dev\boost_1_83_0\bootstrap.bat,会在同目录下…

激活/注册navicat15

一、获取软件 链接:https://pan.baidu.com/s/1F_tiLuLvVFMEz8pDfIvDjw?pwdjjfj 提取码:jjfj 二、安装 安装的过程我就不放了,重点如下 安装完不要打开软件! 安装完不要打开软件! 安装完不要打开软件!…

Spark SQL进阶

DataFrame详解 清洗相关API 去重API 删除空缺值的API 替换缺失值的API from pyspark import SparkConf, SparkContext import os from pyspark.sql import SparkSession# 绑定指定的Python解释器 os.environ[SPARK_HOME] /export/server/spark os.environ[PYSPARK_PYTHON]…

前端面试题集合六(高频)

1、vue实现双向数据绑定原理是什么&#xff1f; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>…

RT-Thread入门笔记3-线程的创建

线程 RT-Thread 中&#xff0c;线程由三部分组成&#xff1a;线程代码&#xff08;入口函数&#xff09;、线程控制块、线程堆栈. 线程代码: 线程控制块 : 线程控制块是操作系统用于管理线程的一个数据结构&#xff0c; 它会存放线程的一些信息&#xff0c; 例如优先级、 线程…