MySQL数据库调优————ORDER BY语句

news2025/1/11 23:49:20

ORDER BY调优的核心原理,原则是利用索引的有序性跳过排序环节

关于ORDER BY语句的一些尝试

我们使用employees表进行尝试,索引情况如下
在这里插入图片描述
在执行计划的结果中,Extra里如果存在,Using filesort则表示,排序没有使用到索引。

explain
select *
from employees
order by first_name,last_name;

结果
在这里插入图片描述
并没有用到索引,发生了全表扫描

explain
select *
from employees
order by first_name,last_name
limit 10;

结果
在这里插入图片描述
这次的查询就用到了索引。为什么一次是ALL,一次是index呢?
因为第一次相当于对整张表进行排序的,排序是基于成本计算的,在优化器发现全表扫描开销更低时,会直接使用全表扫描。而第二次是仅仅对前10条数据进行排序,扫描索引的成本要小于扫面全表,所以用到了索引。
----------------------------------------------------------------------------------------------------------------->

explain
select *
from employees
where first_name = 'Bader'
order by last_name;

结果
在这里插入图片描述
这句SQL是用到了索引排序的,当执行查询时,查找出来的数据为[‘Bader’,last_name[i],emp_no],因为索引是有序的,'Bader’是确定的,那么数据已经按照last_name排好序了,就跳过了排序的环节。
----------------------------------------------------------------------------------------------------------------->

explain
select *
from employees
where first_name < 'Bader'
order by first_name;

结果
在这里插入图片描述
根据执行结果是使用了索引的,因为在执行查询语句时,查找出来的数据为[first_name,last_name,emp_no],这一部分数据已经是按照first_name排好序的,所以不需要再次进行排序了。
----------------------------------------------------------------------------------------------------------------->

explain
select *
from employees
where first_name = 'Bader'
    and last_name > 'Peng'
order by last_name;

结果
在这里插入图片描述
跟上面的同理,因为在执行查询语句时,查找出来的数据为[Bader,last_name[i],emp_no],这一部分数据已经是按照last_name排好序的,所以不需要再次进行排序了。
----------------------------------------------------------------------------------------------------------------->

explain
select *
from employees
order by first_name,emp_no limit 10;

结果
在这里插入图片描述
根据执行结果 ,该语句没有用到索引,因为两个排序字段存在于不同的两个索引中,会先按first_name进行排序,再将相同first_name的数据按照emp_no进行排序。
----------------------------------------------------------------------------------------------------------------->

explain
select *
from employees
order by first_name desc ,last_name asc limit 10;

结果
在这里插入图片描述
因为索引中的两个字段,在进行排序中的升降序不一致,所以无法使用索引。
----------------------------------------------------------------------------------------------------------------->

explain
select *
from employees
where first_name < 'Bader'
order by last_name limit 10;

结果
在这里插入图片描述
根据结果得知,在进行查询时使用了索引,但在排序时使用的是Using filesort。说明排序时没有用到索引。组合索引中part1范围查询,使用part2进行排序是无法使用索引排序的。

排序模式

Using filesort排序原理,目前MySQL使用了三种排序模式

模式一:rowid排序(常规排序)

排序过程

  1. 从表中获取满足where条件的数据。
  2. 对于每条记录,将记录的主键及排序字段(id,order_column)取出放入sort buffer(由sort_buffer_size控制大小)。
  3. 如果sort buffer能存放所有满足条件的(id,order_column),则进行排序;否则,当sort buffer存满后,会将sort buffer中的数据排序并存放到临时文件中。
    • 在没有产生临时文件时,在内存中使用快速排序算法
    • 如果产生了临时文件,则需要利用归并排序算法,从而保证记录有序
  4. 扫描排序好的(id,order_column)数据,并利用id去取select需要返回的其他字段。
  5. 返回结果集。

排序特点

  • 看sort buffer是否能存放查询出来的所有的结果集,如果不满足,就会差生临时文件
  • 一次排序需要两次IO
    • 第一次,把查询出来的(id,order_column)结果集放入sort buffer中;第二次,通过id去获取需要返回的其他字段。由于返回结果是按照order_column进行排序的,所以主键id是乱序的,会存在随机IO的问题。之前文中提到,在用主键id取值前,会按照主键id进行排序,并放入一个缓存中,该缓存大小是由read_rnd_buffer_size控制,接着再去取记录,从而把随机IO转换成顺序IO。

模式二:全字段排序(优化排序)

排序过程

跟第一种模式相比,有几点不同

  • 直接取出表中需要的所有字段,放到sort buffer种
  • 由于sort buffer已经包含了查询需要的所有的字段,因此sort buffer种排序完成后直接返回结果集

全字段排序 vs rowid排序

  • 优点:性能的提升,无需两次IO,因为全字段排序已经将需要的所有字段存储到了sort buffer种,无需再次用主键id去表中获取
  • 缺点:由于全字段排序会将需要的所有的字段放入sort buffer中,所以占用空间比较大,如果sort buffer不够大,那么很容易产生临时文件

排序算法的选择

  • max_length_for_sort_data:当OEDER BY中出现的字段的总长度小于该值,使用全字段排序,反之则使用rowid排序。

模式三:打包字段排序

  • MySQL5.7引入
  • 与模式二工作原理一致,不同点在于会将字段紧密的排列在一起,而不是固定长度的空间。
    • 例如:一个字段定义为VARCHAR(32),值为’yes’;在不打包的情况下占用32字节,打包的情况下2+3字节。

参数汇总

变量作用
sort_buffer_size指定sort buffer的大小
max_length_for_fort_data当ORDER BY中出现字段的总长度小于该值时使用全字段排序,反之使用rowid排序
read_rnd_buffer_size按照主键排序后存放的缓存区大小

使用optimizer_trace分析排序过程

explain展示的排序方式很有限,仅仅是Using filesort,如果我们想了解更多的细节就需要使用optimizer_trace进行分析了。
以下面语句为例:

select *
from employees
where first_name < 'Bader'
order by last_name;

执行

SET OPTIMIZER_TRACE="enabled=on",END_MARKERS_IN_JSON=on;
SET optimizer_trace_offset=-30,optimizer_trace_limit=30;

开启OPTIMIZER_TRACE,执行示例SQL语句,再次执行

select * from information_schema.OPTIMIZER_TRACE where QUERY like '%Bader%';

获取分析结果,将trace字段的内容复制出来进行分析;
我们主要关注的是filesort_summary,

“filesort_summary”: {
“memory_available”: 262144,
“key_size”: 265,
“row_size”: 399,
“max_rows_per_buffer”: 502,
“num_rows_estimate”: 927744,
“num_rows_found”: 22287,
“num_initial_chunks_spilled_to_disk”: 0,
“peak_memory_used”: 204314,
“sort_algorithm”: “std::sort”,
“unpacked_addon_fields”: “using_priority_queue”,
“sort_mode”: “<varlen_sort_key, additional_fields>”
}

其相关字段解读如下:

  • memory_available:可用内存,其实就是fort_buffer_size设置的值
  • num_rows_found:有多少条数据参与排序,越小越好
  • num_initial_chunks_spilled_to_disk:产生了几个临时文件,0表示完全基于内存排序
  • sort_mode
    • <varlen_sort_key,rowid>:使用了rowid排序模式
    • <varlen_sort_key, additional_fields>:使用了全字段排序模式
    • <varlen_sort_key, packed_additional_fields>:使用了打包字段排序模式

如何调优ORDER BY

  • 利用索引,防止filesort发生
  • 如果发生了filesort,且无法避免,就要对filesort进行优化

如何调优filesort

  • 调大sort_buffer_size,减少/避免临时文件的产生,从而进行的归并操作
    • 当optimizer_trace的结果中 num_initial_chunks_spilled_to_disk的值较大时,需要调整
    • show status like ‘%sort_merge_passes%’;查看发生归并操作的次数
  • 调大read_rnd_buffer_size,让一次顺序IO返回更多的结果
  • 设置合理的max_length_for_sort_data的值

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

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

相关文章

JavaScript 代码规范

文章目录JavaScript 代码规范JavaScript 代码规范变量名空格与运算符代码缩进语句规则对象规则每行代码字符小于 80命名规则HTML 载入外部 JavaScript 文件使用 JavaScript 访问 HTML 元素文件扩展名使用小写文件名JavaScript 代码规范 所有的 JavaScript 项目适用同一种规范。…

PADS设计基础

目录 1 PADS设计流程简介 2 快捷键 2.1鼠标指令 2.2快捷键 3元件库概述 3.1元件库分类 3.2创建元件库 3.3新的元件类型的创建 3.3.1 插座的创建 1 PADS设计流程简介 常规PADS设计流程:设计启动→建库→原理图设计→网表调入→布局→布线→验证优化→设计资料输出→加…

VUE3源码分析————rollup打包遇见问题

文章目录一、require无法使用二、The requested module xxx does not provide an export named default三、__filename无法使用四、path.resolve() arguments must be a string一、require无法使用 在使用rullup打包的过程中&#xff0c;我们需要在最外层的package.json文件中…

时间序列分解法

影响时间序列变化的因素通常由长期趋势&#xff0c;季节变动&#xff0c;周期变动&#xff0c;不规则变动几部分组成 长期趋势指现象在较长时期内持续发展变化的一种趋向或状态。季节变动是由于季节的变化引起的现象发展水平的规则变动&#xff08;波动长度固定&#xff09;周…

n阶数字回转方阵 ← 模拟法

【问题描述】 请编程输出如下数字回旋方阵。 【算法代码】 #include <bits/stdc.h> using namespace std;const int maxn100; int z[maxn][maxn];void matrix(int n) {int num2;z[0][0]1;int i0,j1;while(i<n && j<n) {while(i<j) z[i][j]num;while(j&…

Redis底层原理(持久化+分布式锁)

Redis底层原理 持久化 Redis虽然是个内存数据库&#xff0c;但是Redis支持RDB和AOF &#xff08;Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中 &#xff1b;Appen…

基于粒子群优化算法的电动汽车充放电V2G研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

CMMI-质量保证

质量保证&#xff08;Quality Assurance, QA&#xff09;的目的是提供一种有效的人员组织形式和管理方法&#xff0c;通过客观地检查和监控“过程质量”与“产品质量”&#xff0c;从而实现持续地改进质量。质量保证是一种有计划的、贯穿于整个产品生命周期的质量管理方法。质量…

Java ~ Collection/Executor ~ LinkedBlockingDeque【总结】

一 概述 简介 LinkedBlockingDeque&#xff08;链接阻塞双端队列&#xff09;类&#xff08;下文简称链接阻塞双端队列&#xff09;是BlockingDeqeue&#xff08;阻塞双端队列&#xff09;接口的唯一实现类&#xff0c;采用链表的方式实现。链接阻塞双端队列与LinkedBlockingQu…

【Java|golang】1792. 最大平均通过率---封装最小堆

一所学校里有一些班级&#xff0c;每个班级里有一些学生&#xff0c;现在每个班都会进行一场期末考试。给你一个二维数组 classes &#xff0c;其中 classes[i] [passi, totali] &#xff0c;表示你提前知道了第 i 个班级总共有 totali 个学生&#xff0c;其中只有 passi 个学…

Windows使用ssh协议远程连接ubuntu linux系统

Windows使用ssh协议远程连接ubuntu linux系统一、Windows远程连接ubuntu linux系统二、开启ubuntu ssh服务三、获取ubuntu子系统的ip地址四、从windows上通过ssh连接到ubuntu子系统五、设置ubuntu系统ssh自启动&#xff08;18.04&#xff09;一、Windows远程连接ubuntu linux系…

【JavaScript】JavaScript基本使用方法

如何回复程序员发来的短信&#xff1a;Hello world —hello nerd. 前言&#xff1a; 大家好&#xff0c;我是程序猿爱打拳。今天我给大家讲解的是初识JavaScript中基本组成成分、引入方法、输入输出语句&#xff0c;并用源码与效果图的方式展示给大家。 目录 1.JavaScript组成…

手机文字转语音软件哪个好用?超火的两款好用的文字转语音软件

有很多小伙伴对短视频配音比较感兴趣&#xff0c;但方方面面了解得不多&#xff0c;比如&#xff1a;配音有哪几种方法&#xff1f;需要注意些什么&#xff1f;用手机就可以操作么&#xff1f;好用的文字转语音软件有哪些&#xff1f;这篇文&#xff0c;小编就带大家简单了解一…

(C语言篇)扫雷的实现

文章目录 一、开始时的基本思维&#xff1a;二、进入游戏的逻辑(test.c文件中实现)三、游戏的编写 1. 初始化棋盘 I. test.cII. game.hIII. game.c 2.打印棋盘 I. test.cII. game.hIII. game.c 3.布置雷 I. test.cII. game.hIII. game.c 4.排查雷 I. test.cII. game.hIII. gam…

Java集合学习之Map

1.什么是Map Java里的Map接口是一个集合根接口&#xff0c;表示一个 键值对&#xff08;Key-Value&#xff09; 的映射。 简单来说就是键和值是一对的&#xff0c;每一个 Key都有唯一确定的 Value对应。 其中要求 键&#xff08;Key&#xff09; 唯一&#xff0c;因为是按照…

宏观经济研究:全国各省、地级市-社会融资规模增量数据(包含总额及8类明细)2013-2021年

数据来源&#xff1a;中国人民银行 时间跨度&#xff1a;2013-2021年&#xff0c;季度数据&#xff08;累计数&#xff09; 区域范围&#xff1a;全国31省份 数据字段&#xff1a; 31个省市社会融资规模增量数据&#xff0c;包含社会融资总额以及8类明细&#xff08;人民币…

12-Composer的配置与使用详解

1、自定义类与非类的自动加载与测试 # composer> php 包管理工具 &#xff0c;类似npm1.自己写的类&#xff0c;函数&#xff0c;接口&#xff0c;常量等全局成员&#xff0c;通过自动加载来实现按需加载 2.自己写的代码&#xff0c;有哪些依赖&#xff0c;用到了哪些外部成…

MySQL数据库调优————GROUP BY及DISTINCT优化

GROUP BY 三种处理GROUP BY的方式 松散索引扫描&#xff08;Loose Index Scan&#xff09;紧凑索引扫描&#xff08;Tight Index Scan&#xff09;临时表&#xff08;Temporary table&#xff09; 三种方式的性能一次递减 松散索引扫描 无需扫描满足条件的所有索引键即可返…

基于SSM,Spring, BootStrap 毕业设计管理系统的设计与实现

目录 一.前言介绍 二、主要技术 2.1 SSM框架介绍 2.2 MYSQL数据库 2.3 持久层框架MyBatis 2.4 前端框架BootStrap 三. 系统设计 3.1 系统架构设计 3.2 系统功能模块 3.2.1 学生模块 3.2.2 教师模块 3.2.3 管理员模块 四、数据库设计 4.1 数据分析 4.2 概念设计 …

SpringBoot搭建SpringMVC项目

前言据我的了解&#xff0c;现在不管是大公司或是小公司&#xff0c;如果使用java开发一个web项目&#xff0c;大部分都会选择使用SpringBoot&#xff0c;关于Springboot的好处&#xff0c;就不在这里过多赘述&#xff0c;总之Springboot有一套完整的生态&#xff0c;从项目构建…