排序相关问题

news2024/11/25 19:27:45

本篇博客在B站做了内部分享,标题为「排序相关问题」

MySQL的ORDER BY有两种排序实现方式:

  1. 利用有序索引获取有序数据
  2. (不得不进行)文件排序

在explain中分析时,利用有序索引获取有序数据显示Using index,文件排序显示Using filesort

alt



1. 能够 利用有序索引获取有序数据 的条件比较苛刻


以下几种优化方式,可能使order by利用到索引,而无需进行filesort:

1、ORDER BY的索引优化。如果一个SQL语句形如:
SELECT [column1],[column2],…. FROM [TABLEORDER BY [sort];
在[sort]这个栏位上建立索引就可以实现利用索引进行order by 优化。
 
2、WHERE + ORDER BY的索引优化,形如:
SELECT [column1],[column2],…. FROM [TABLEWHERE [columnX] = [valueORDER BY [sort];
建立一个联合索引(columnX,sort)来实现order by 优化。
 
注意:如果columnX对应多个值,如下面语句就无法利用索引来实现order by的优化
SELECT [column1],[column2],…. FROM [TABLEWHERE [columnX] IN ([value1],[value2],…) ORDER BY[sort];
 
3、WHERE+ 多个字段ORDER BY
SELECT * FROM [tableWHERE uid=1 ORDER x,y LIMIT 0,10;
建立索引(uid,x,y)实现order by的优化,比建立(x,y,uid)索引效果要好得多。
alt

Order By不能使用索引来优化排序的情况:

  • 对不同的索引键做 ORDER BY :(key1,key2分别建立索引)

      SELECT * FROM t1 ORDER BY key1, key2;

  • 在非连续的索引键部分上做 ORDER BY:(key_part1,key_part2建立联合索引;key2建立索引)

      SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2;

  • 同时使用了 ASC 和 DESC:(key_part1,key_part2建立联合索引)

      SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;

  • 用于搜索记录的索引键和做 ORDER BY 的不是同一个:(key1,key2分别建立索引)

      SELECT * FROM t1 WHERE key2=constant ORDER BY key1;

  • 如果在WHERE和ORDER BY的栏位上应用表达式(函数)时,则无法利用索引来实现order by的优化

      SELECT * FROM t1 ORDER BY YEAR(logindate) LIMIT 0,10;

CREATE TABLE `weekxxxxxnor_detail` (
  `id` int(11unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `mid` int(11NOT NULL DEFAULT '0' COMMENT '用户ID',
  `hid` int(11NOT NULL DEFAULT '0' COMMENT '荣誉ID',
  `word` varchar(10NOT NULL DEFAULT '' COMMENT '字',
  `text` varchar(20NOT NULL DEFAULT '' COMMENT '文案',
  `description` varchar(40NOT NULL DEFAULT '' COMMENT '说明',
  `xxxxx_date` date NOT NULL DEFAULT '0000-00-00' COMMENT 'xx生成日期(每周日)',
  `ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `ix_mtime` (`mtime`),
  KEY `ix_mid_honor_date` (`mid`,`honor_date`)
ENGINE=InnoDB AUTO_INCREMENT=149628474 DEFAULT CHARSET=utf8 COMMENT='xxxxxx详情记录'


详细参见 https://note.youdao.com/web/#/file/WEB00c9fc9e542b90ea18d0c3cc53e74d96/note/WEBcb79302cc9f9cadb9d543963f9793baf/

搜索 ENGINE=InnoDB AUTO_INCREMENT=149628474 DEFAULT CHARSET=utf8 COMMENT=

alt
alt



2. filesort


2.1 在内存中可能用 堆排序或快速排序,


具体使用哪一种排序方式是优化器决定的,基本原则如下

快速排序算法:大量排序
堆排序算法:排序量不大

快速排序和堆排序都是不稳定的排序算法,对于重复值不能保证顺序。这就是Order by排序可能会不稳定的原因

alt

之前遇到的坑:

alt

2.1.1 在把数据加载到BUFFER内部时有两种方式:


  • 双路排序:(rowid排序/二次访问排序/回表排序模式)

首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行指针信息,然后在sort buffer 中进行排序。排序后再把查询字段依照行指针取出,共执行两次磁盘io。

  • 单路排序:MySQL4.1之后新增(全字段排序/一次访问排序)

一次性取出满足条件行的所有字段,然后在sort buffer中进行排序。 执行一次磁盘io。代价是对内存占用大


使用哪种方式,取决于设定的系统参数max_length_for_sort_data(默认为1K) 和Query 语句所取出的字段类型大小总和的大小关系, 来判定是使用双路排序还是单路排序。

如果单行的长度超过max_length_for_sort_data的值,MySQL就认为单行太大,使用双路排序方式;

如果 max_length_for_sort_data更大,则使用第二种优化后的算法。


所以如果希望 ORDER BY 操作的效率尽可能的高,一定要注意max_length_for_sort_data 参数的设置。

alt

2.2 在外部使用多路归并排序算法:


alt

2.3 整个filesort的过程如下:


(1)根据表的索引或者全表扫描,读取所有满足条件的记录。

(2)对于每一行,存储一对值到缓冲区(排序列和行记录指针,或者是排序列和查询需要的所有列),缓冲区的大小为sort_buffer_size大小(默认为1M)。

(3)当缓冲区满后,运行一个快速排序(qsort; 数据量不大时也可能用堆排序)来将缓冲区中数据排序,并将排序完的数据存储到一个临时文件,并保存一个存储块的指针,当然如果缓冲区不满,则不会重建临时文件了。

(4)重复以上步骤,直到将所有行读完,并建立相应的有序的临时文件。

(5)对块级进行排序,使用归并排序算法,通过对几个临时文件的指针来不断交换数据,最终达到几个文件,都是有序的。

(6)重复5直到所有的数据都排序完毕。

(7)采取顺序读的方式,将每行数据读入内存(这里读取数据时并不是一行一行读),并取出数据传到客户端,读取缓存大小由read_rnd_buffer_size来指定。

alt

参考:

https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html#order-by-filesort-in-memory

本文由 mdnice 多平台发布

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

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

相关文章

macm1环境下jdk版本切换

macm1环境下jdk版本切换 本文目录 macm1环境下jdk版本切换下载jdk安装动态切换jdk终端生效全局生效 参考 下载jdk oracle官方源下载地址 https://www.oracle.com/java/technologies/downloads/#jdk17-mac Azul下载地址 https://www.azul.com/downloads/?packagejdk#download…

Autosar-Runnables(可运行实体)

文章目录 Runnable entities (简称Runnables)一、Runnables的定义二、Runnables的作用三、DaVinci配置总结Runnable entities (简称Runnables) 包含实际实现的函数(具体的逻辑算法或者操作) Runables由RTE周期性、或事件触发调用(如,当接收到数据、被操作调用) 一、Runna…

时序预测 | MATLAB实现ELM极限学习机时间序列预测未来

时序预测 | MATLAB实现ELM极限学习机时间序列预测未来 目录 时序预测 | MATLAB实现ELM极限学习机时间序列预测未来预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.MATLAB实现ELM极限学习机时间序列预测未来; 2.运行环境Matlab2018及以上,data为数…

MYSQL MHA实现故障转移和自动切换

目录 1、MHA理论: 1.1、MHA概述 1.2、MHA的组成: 1.3、特点: 1.4、传统的MySQL主从架构存在一些常见的问题: 1.5、MHA工作原理总结如下 1.6、 故障切换备选主库的算法: 2、 故障转移实验 2.1、搭建 MySQL MHA…

Linux知识点 -- 网络编程套接字

Linux知识点 – 网络编程套接字 文章目录 Linux知识点 -- 网络编程套接字一、预备知识1.认识端口号2.套接字3.TCP协议与UDP协议4.网络字节序 二、socket编程接口1.socket常见API2.sockaddr结构 三、UDP套接字编程1.直接打印客户端信息2.执行客户端发来的指令3.多用户聊天4.在wi…

ALBEF、VLMO、BLIP、BLIP2、InstructBLIP要点总结(WIP)

ALBEF(ALign BEfore Fuse) 为什么有5个loss? 两个ITC两个MIM1个ITM。ITM是基于ground truth的,必须知道一个pair是不是ground truth,同时ITM loss是用了hard negative,这个是和Momentum Distillation&…

优化爬虫效率:利用HTTP代理进行并发请求

网络爬虫作为一种自动化数据采集工具,广泛应用于数据挖掘、信息监测等领域。然而,随着互联网的发展和网站的增多,单个爬虫往往无法满足大规模数据采集的需求。为了提高爬虫的效率和性能,我们需要寻找优化方法。本文将介绍一种利用…

(位运算) 剑指 Offer 56 - I. 数组中数字出现的次数 ——【Leetcode每日一题】

❓剑指 Offer 56 - I. 数组中数字出现的次数 难度:中等 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是 O ( n ) O(n) O(n),空间复杂度是 O ( 1 ) O(1) O(1)。 示例 …

开源对象存储系统minio部署配置与SpringBoot客户端整合访问

文章目录 1、MinIO安装部署1.1 下载 2、管理工具2.1、图形管理工具2.2、命令管理工具2.3、Java SDK管理工具 3、MinIO Server配置参数3.1、启动参数:3.2、环境变量3.3、Root验证参数 4、MinIO Client可用命令 官方介绍: MinIO 提供高性能、与S3 兼容的对…

MPDIoU: A Loss for Efficient and Accurate Bounding BoxRegression

MPDIoU: A Loss for Efficient and Accurate Bounding BoxRegression MPDIoU:一个有效和准确的边界框损失回归函数 摘要 边界框回归(Bounding box regression, BBR)广泛应用于目标检测和实例分割,是目标定位的重要步骤。然而,当预测框与边界框具有相同的…

vue3 + elementplus Cannot read properties of null (reading ‘isCE‘)

使用命令行直接下载的element-plus,使用时会报错。 卸载掉,然后在项目根目录下,使用vue ui安装依赖, 即可使用

逆向大漠插件/用VB6.0实现后台鼠标移动和后台鼠标左键点击

自动化设计软件,在一款做门的设计软件CypCut6.3 上实现了自动化勾选了 复选框。一切都是基于后台的。 Private Const GW_CHILD 5 Private Const GW_HWNDFIRST 0 Private Const GW_HWNDNEXT 2 Public Declare Function FindWindow Lib "user32" Alias &…

数据结构笔记:MX四叉树 VS PR 四叉树

个人理解,不一定对,还望批评指教! 比如我们分别建一个数 MX四叉树PR四叉树插入(1.5,5.5)插入(6.5,15.5)插入(9.5,5.5)插入(11.5,3.5&#xff09…

华为云云服务器评测|云耀云服务器实例基础使用实践

🦖我是Sam9029,一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 **🐱‍🐉🐱‍🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求…

Java复习-20-接口(1)

接口的定义及使用 如果相对外部隐藏全部的实现细节,就要通过接口来实现。 接口的定义 使用interface关键字来定义。由于接口描述的是一个公共的定义标准,所以在接口之中所有的抽象方法的访问权限都为public interface IMessage{ // 为了区分接口&…

一步一步分析将数据响应式实现出来

写在前面 vue2 的数据响应式已经非常成熟且过时了,但是相信很多人还是对原理的东西一知半解,甚至还是不知道他究竟是怎么实现的,今天我们就试着一步一步分析看看响应式需要解决哪些问题,具体的问题难点是什么? 数据响应…

【计算机组成 课程笔记】5.1 处理器的设计步骤

课程链接: 计算机组成_北京大学_中国大学MOOC(慕课) 5 - 1 - 501-处理器的设计步骤(14-49--)_哔哩哔哩_bilibili 处理器,或者说是CPU,是现代计算机中最为复杂的一个部件。不过先不要劝退,要设计一个简单但是…

1343. 大小为 K 且平均值大于等于阈值的子数组数目

1343. 大小为 K 且平均值大于等于阈值的子数组数目 C代码&#xff1a;滑动窗口 // 窗口长度固定、返回窗口平均值>threshold的窗口个数int numOfSubarrays(int* arr, int arrSize, int k, int threshold){int cnt 0;int l 0;int sum 0;for (int r 0; r < arrSize; r…

轻松制作玩具小程序商城

随着移动互联网的快速发展&#xff0c;小程序成为了各行各业的新宠儿。想要快速搭建一个属于自己的小程序商城吗&#xff1f;乔拓云平台将为你提供最简单的解决方案。下面就跟随我的步骤&#xff0c;一起来学习如何搭建一个玩具小程序商城吧&#xff01; 首先&#xff0c;我们需…

微机原理与技术(2)8086微处理器

8086微处理器 考点介绍功能和介绍后续会继续更新&#xff0c;点赞follow me继续学习 考点介绍 考点一: 掌握8086/8088CPU的功能构成及流水线技术&#xff0c;理解流水线管理规则。2.1 8086/8088 CPU的功能构成2.2 8086/8088CPU的流水线技术考点二:掌握8086/8088CPU寄存器的组成…