当前位置: 首页 > news >正文

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

文章目录

  • MySQL45讲 第十六讲 “order by”是怎么工作的?
    • 一、引言
    • 二、全字段排序
      • (一)索引创建与执行情况分析
      • (二)执行流程
      • (三)查看是否使用临时文件
    • 三、rowid 排序
      • (一)参数控制与算法改变
      • (二)执行流程
      • (三)全字段排序和rowid 排序性能对比
    • 四、利用联合索引避免排序
      • (一)创建联合索引
      • (二)执行流程简化
      • (三)覆盖索引优化
    • 五、总结与思考

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

一、引言

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

例子:假设你要查询城市是“杭州”的所有人名字,并且按照姓名排序返回 前1000个人的姓名、年龄。

假设这个表的部分定义是这样的:

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;

这时,你的SQL语句可以这么写:

select city,name,age from t where city='杭州' order by name limit 1000;

二、全字段排序

(一)索引创建与执行情况分析

  1. MySQL会给每个线程分配一块内存用于排序,这块内存称为sort_buffer。为避免全表扫描,需在 city 字段创建索引。

    在这里插入图片描述

  2. 使用 explain 命令查看执行情况,Extra 字段中的 Using filesort 表示需要排序,MySQL 会为每个线程分配 sort_buffer 内存用于排序。
    在这里插入图片描述

(二)执行流程

  1. 初始化 sort_buffer,确定放入 namecityage 三个字段。
  2. city 索引找到满足条件的第一个主键 id
  3. 到主键 id 索引取出整行,取相关字段值存入 sort_buffer
  4. city 索引取下一个记录的主键 id,重复 3、4 步直到不满足条件。
  5. sort_buffer 中的数据按 name 字段做快速排序(可能在内存或使用外部排序,取决于 sort_buffer_size 参数和排序数据量)。
  6. 取前 1000 行返回给客户端。

(三)查看是否使用临时文件

  1. 通过设置 optimizer_traceenabled=on,计算执行语句前后 performance_schema.session_statusInnodb_rows_read 的差值,并查看 OPTIMIZER_TRACE 结果中的 number_of_tmp_files,可确定是否使用临时文件。若该值大于 0,表示使用了外部排序,MySQL 将数据分成多份排序后合并;若为0,表示可在内存中完成排序。

  2. 下图中的number_of_tmp_files=12代表MySQL将需要排序的数据分成12份,每一份单独排序后存在这些临时文件中。然后把这12个有序文件再合并成一个有序的大文件。

    在这里插入图片描述


三、rowid 排序

全字段排序算法过程里面,只对原表的数据读了一遍,剩下的操作都是在sort_buffer和临时文件中执行的。如果查询要返回的字段很多的话,那么sort_buffer里面要放的字段数太多,即行长度过长,这样内存里能够同时放下的行数很少,要分成很多个临时文件,排序的性能会很差。这时候就需要使用rowid排序

(一)参数控制与算法改变

SET max_length_for_sort_data = 16;

  1. max_length_for_sort_data 参数设置为较小值(如 16),且单行长度超过该值时,MySQL 采用 rowid排序算法。此算法放入 sort_buffer 的字段只有要排序的列(如 “name”)和主键 id

(二)执行流程

  1. 初始化 sort_buffer,确定放入 nameid 字段。

  2. city 索引找到满足条件的第一个主键 id

  3. 到主键 id 索引取出整行,取 nameid 字段存入 sort_buffer

  4. city 索引取下一个记录的主键 id,重复 3、4 步直到不满足条件。

  5. sort_buffer中的数据按 name 排序。

  6. 遍历排序结果取前 1000 行,按 id 值回原表取出 citynameage 字段返回给客户端。此算法多了一次回表操作,但在单行数据较大时,可在排序过程中一次排序更多行。

在这里插入图片描述

(三)全字段排序和rowid 排序性能对比

  1. 全字段排序在内存足够时优先选择,可直接从内存返回结果,减少磁盘访问
  2. rowid 排序在内存较小时使用,虽排序时能处理更多行,但需回表取数据,增加磁盘读操作。

四、利用联合索引避免排序

(一)创建联合索引

  1. 创建 cityname 的联合索引(如 city_user (city, name)),可确保从该索引取出行时按 name 递增排序,无需再进行排序操作。

    在这里插入图片描述

  2. 无需继续创建临时表和排序,使用explain指令查看,Extra字段已经没有Using filesort,证明

    在这里插入图片描述

(二)执行流程简化

  1. 从联合索引找到满足条件的第一个主键 id

  2. 到主键 id 索引取整行相关字段值直接返回。

  3. 从联合索引取下一个记录主键 id,重复 2 步直到满足条件结束。

    在这里插入图片描述

(三)覆盖索引优化

  1. 进一步创建 citynameage 的联合索引(如 city_user_age (city, name, age)),可利用覆盖索引,直接从索引获取数据返回,无需回表从主键索引取数据,性能更快,但需权衡索引维护代价。覆盖索引是指,索引上的信息足够满足查询请求,不需要回到主键索引上去取数据。

  2. 这样整个查询语句的执行流程就变成了:

    • 从索引(city,name,age)找到第一个满足city='杭州’条件的记录,取出其中的city、name和age 这三个字段的值,作为结果集的一部分直接返回;
    • 从索引(city,name,age)取下一个记录,同样取出这三个字段的值,作为结果集的一部分直接返回;
    • 重复执行步骤2,直到查到第1000条记录,或者是不满足city='杭州’条件时循环结束。

    在这里插入图片描述


五、总结与思考

MySQL 中 order by 语句有多种执行算法,开发人员应清楚其排序逻辑和系统资源消耗,根据实际情况选择合适方案。

  • 全字段排序可能需要使用临时表进行排序,在字段过多的情况下性能可能会很差。
  • 为了减少字段过长导致的排序性能下降,rowid排序算法放入 sort_buffer 的字段只有要排序的列(如 “name”)和主键 id
  • 如果需要进一步提高性能,可以采取联合索引乃至覆盖索引(字段已排序),这样就可以避免排序,但是需要消耗空间存储索引和维护索引为代价。

相关文章:

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

文章目录 MySQL45讲 第十六讲 “order by”是怎么工作的?一、引言二、全字段排序(一)索引创建与执行情况分析(二)执行流程(三)查看是否使用临时文件 三、rowid 排序(一)参…...

智慧商城项目-VUE2

实现效果 项目收获 通过本项目的练习,可以掌握以下内容: 创建项目 ##基本创建 基于 VueCli 自定义创建项目架子,并对相关的配置进行选择 vue create demo-shopping调整目录 删除文件 删除初始化的一些默认文件 src/assets/logo.pngsrc/components…...

音视频入门基础:FLV专题(22)——FFmpeg源码中,获取FLV文件音频信息的实现(中)

本文接着《音视频入门基础:FLV专题(21)——FFmpeg源码中,获取FLV文件音频信息的实现(上)》,继续讲解FFmpeg获取FLV文件的音频信息到底是从哪个地方获取的。本文的一级标题从“四”开始。 四、音…...

Chrome与火狐哪个浏览器的性能表现更好

在数字时代,浏览器是我们日常生活中不可或缺的工具。无论是工作、学习还是娱乐,一个好的浏览器都能显著提高我们的效率和体验。市场上有许多优秀的浏览器,其中Google Chrome和Mozilla Firefox无疑是最受欢迎的两款。本文将比较这两款浏览器的…...

uniapp在js方法中,获取当前用户的uid(uni-id-user)表中的用户id

// 1.判断当前用的权限 let uid uniCloud.getCurrentUserInfo().uid //获取当前用户的uid // 用户uid等于发布者id或者用户权限等于admin或者用户角色等于webmaster if (uid this.item.user_id[0]._id || this.uniIDHasRole…...

影响神经网络速度的因素- FLOPs、MAC、并行度以及计算平台

影响神经网络速度的四个主要因素分别是 FLOPs(浮点操作数)、MAC(内存访问成本)、并行度以及计算平台。这些因素共同作用,直接影响到神经网络的计算速度和资源需求。 1. FLOPs(Floating Point Operations&a…...

【万字详解】如何在微信小程序的 Taro 框架中设置静态图片 assets/image 的 Base64 转换上限值

设置方法 mini 中提供了 imageUrlLoaderOption 和 postcss.url 。 其中: config.limit 和 imageUrlLoaderOption.limit 服务于 Taro 的 MiniWebpackModule.js , 值的写法要 ()KB * 1024。 config.maxSize 服务于 postcss-url 的…...

复合选择器,CSS特性,背景属性,显示模式(HTML)

目录 复合选择器,CSS特性,背景属性,显示模式知识点: 练习一: 练习二: 复合选择器,CSS特性,背景属性,显示模式知识点: 复合选择器:后代选择器 :父选择器 子选择器(中间用空格隔开) eg:对div中的span进行设置,会对后代中的所有span都进行设置 选中所有后代(后代选择器.html)…...

加密货币行业与2024年美国大选

加密货币行业经历了近十年的飞速发展,尤其是在比特币、以太坊等主要加密资产的兴起之后,越来越多的美国人开始将其视为一种财富积累或交易的工具。然而,尽管这一新兴行业的市场规模在持续扩大,但加密货币仍面临着重重监管难题&…...

Hive SQL中判断内容包含情况的全面指南

Hive SQL中判断内容包含情况的实用指南 在 Hive SQL 的数据处理与分析世界里,判断字段是否包含特定内容是一项非常重要的操作。今天,我将为大家详细介绍 Hive SQL 中实现这一功能的多种方法,并附上相应的表创建和数据插入语句。 一、准备工作 - 表创建与数据插入 首先,我…...

匿名管道 Linux

目录 管道 pipe创建一个管道 让子进程写入,父进程读取 如何把消息发送/写入给父进程 父进程该怎么读取呢 管道本质 结论:管道的特征: 测试管道大小 写端退了,测试结果 测试子进程一直写,父进程读一会就退出 …...

苍穹外卖WebSocket无法建立连接 (修改前端代码)

我在部署nginx 反向代理服务器时,把80端口改成了90端口(不与80端口的Tomcat冲突)。 但黑马的资料里定义了前端连接nginx的端口号默认为80,造成连接不上的问题,此时只需要修改前端的端口号,使其知道如何连接到修改后的后端端口。 …...

音频内容理解

音频内容理解是音频处理和理解领域的一个重要方向,它涉及到从环境声音中提取语义信息,并能够对这些声音进行解释和描述。以下是音频内容理解的几个关键应用: 1. 音频问答(Audio Question Answering, AQA) 在这个任务…...

MQTT实用示例集:Air201版

今天贴出的是Air201版关于MQTT实用示例集,希望大家喜欢。 本示例教你通过使用脚本代码,对Air201模组进行MQTT链接操作。 操作例程包括: MQTT单链接 MQTT多链接 MQTT SSL不带证书链接 MQTT SSL带证书链接 大家可根据自身需求&#xff0c…...

Day23 opencv图像预处理

图像预处理 在计算机视觉和图像处理领域,图像预处理是一个重要的步骤,它能够提高后续处理(如特征提取、目标检测等)的准确性和效率。OpenCV 提供了许多图像预处理的函数和方法,常见的操作包括图像空间转换、图像大小调…...

优化模型训练过程中的显存使用率、GPU使用率

参考:https://blog.51cto.com/u_16099172/7398948 问题:用小数据集训练显存使用率、GPU使用率正常,但是用大数据集训练GPU使用率一直是0. 小数据: 大数据: 1、我理解GPU内存占用率显存使用率,由模型的大小…...

RocketMQ学习笔记

RocketMQ笔记 文章目录 一、引言⼆、RocketMQ介绍RocketMQ的由来 三、RocketMQ的基本概念1 技术架构2 部署架构 四、快速开始1.下载RocketMQ2.安装RocketMQ3.启动NameServer4.启动Broker5.使⽤发送和接收消息验证MQ6.关闭服务器 五、搭建RocketMQ集群1.RocketMQ集群模式2.搭建主…...

Linux第三讲:环境基础开发工具使用

Linux第三讲:环境基础开发工具使用 1.Linux软件包管理器yum1.1什么是软件包管理器1.2操作系统生态问题1.3什么是yum源 2.vim详解2.1什么是vim2.2vim的多模式讲解2.2.1命令模式的诸多指令2.2.1.1gg和nshiftg2.2.1.2shift$和shift^2.2.1.3上、下、左、右2.2.1.4w和b2.…...

日本TikTok直播的未来:专线网络助力创作者突破极限

近年来,随着短视频平台的崛起,尤其是TikTok(国际版抖音)成为全球范围内广受欢迎的社交娱乐平台,直播功能的加入无疑为内容创作者提供了更广阔的展示舞台。在日本,TikTok直播不仅使得年轻人能够实时与粉丝互…...

如何在家庭网络中设置静态IP地址:一份实用指南

在家庭网络环境中,IP地址扮演着至关重要的角色。大多数家庭用户依赖路由器的DHCP(动态主机配置协议)来自动分配IP地址,但在某些情况下,手动设置静态IP地址能为家庭网络带来更多的便利性与稳定性,尤其是在涉…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

32单片机——基本定时器

STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...