聊聊MySQL是如何处理排序的
本文分享自华为云社区《MySQL怎样处理排序️如何优化需要排序的查询?》,作者:菜菜的后端私房菜。
前言
在MySQL的查询中常常会用到 order by
和 group by
这两个关键字
它们的相同点是都会对字段进行排序,那查询语句中的排序是如何实现的呢?
当使用的查询语句需要进行排序时有两种处理情况:
- 当前记录本来就是有序的,不需要进行排序
- 当前记录未保持顺序,需要排序
使用索引保证有序
对于第一种情况,常常是使用二级索引中索引列的有序来保证结果集有序,从而不需要进行排序
对于表a,为a2建立二级索引,那么在二级索引上a2就是有序的
CREATE TABLE `a` (
`a1` int(11) NOT NULL AUTO_INCREMENT,
`a2` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
`a3` varchar(255) DEFAULT NULL,
PRIMARY KEY (`a1`),
KEY `idx_a2` (`a2`)
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=utf8;
select * from a order by a.a2 limit 10
当优化器选择使用a2索引时,a2列的记录本身就是有序的,因此不需要再使用其他开销进行排序
当然,优化器也有可能不使用a2索引(当优化器认为使用a2回表开销太大时会使用全表扫描)
当优化器使用的索引上a2无序时,则会通过其他手段对结果进行排序
filesort
当执行计划的Extra附加信息中出现 Using filesort
时,会使用sort_buffer对结果进行排序
sort_buffer是一块用于排序的内存,sort_buffer可能存放查询需要的所有字段,也可能只存放需要排序的字段和主键
show variables like 'max_length_for_sort_data'
当查询需要的字段长度小于 max_length_for_sort_data
时,则会将查询需要的所有字段放入sort_buffer中,然后对需要排序的列进行排序,最后返回结果
当查询需要的字段长度大于 max_length_for_sort_data
时,只会将需要排序的字段和主键值放入sort_buffer中,等到排序后再去查询聚簇索引获取需要查询的列(相当于又多了一次回表)
在sort_buffer中进行排序时,如果内存足够则会在内存中进行排序,如果内存不够则会使用磁盘的临时文件来辅助排序
开启 optimizer_trace
可以查看是否使用临时文件辅助排序
#开启优化器追踪
SET optimizer_trace='enabled=on';
#sql语句
select * from student order by student_name limit 10000;
#查看优化器追踪的信息
SELECT * FROM `information_schema`.`OPTIMIZER_TRACE`\G;
排序使用的算法是归并算法,先分割成多个小文件排序再进行合并
其中number_of_tmp_files
为使用到的临时文件数量,sort_buffer_size
为sort_buffer大小
因此当使用order by、group by等需要排序的关键字时,最好建立合适的索引
如果数据量小可以在sort buffer中排序,如果数据量太大还需要与磁盘交互
总结
当查询语句需要排序时会分为不用排序和需要排序两种情况
当使用的索引有序时则不用再进行排序,通过索引来保证有序
当使用的索引无序时则会使用sort_buffer进行排序,当查询字段的长度未超过限制时,sort_buffer中每条记录会存储需要查询的列
如果超过限制,则sort_buffer只会存储需要排序的列和主键值,排序后再通过主键值进行回表获取需要查询的列
当数据量太大不够在内存中排序完,会使用磁盘页辅助排序,使用归并算法将排序数据分散在多个页再合并
可以通过追踪优化器 optimizer_trace 分析内容查看辅助页的数量等信息
为需要排序的列建立合适的索引,避免使用磁盘页辅助排序
当无法使用索引时可以调整sort buffer 或 max_length_for_sort_data(谨慎)
聊聊MySQL是如何处理排序的的更多相关文章
- 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)
redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...
- 聊聊MySQL的加锁规则《死磕MySQL系列 十五》
大家好,我是咔咔 不期速成,日拱一卒 本期来聊聊MySQL的加锁规则,知道这些规则后可以判断SQL语句的加锁范围,同时也可以写出更好的SQL语句,防止幻读问题的产生,在能力范围内最大程度的提升MySQ ...
- Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题
Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题 表更描述: 将mysql数据库中的worktask表添加ishaspic字段. 具体操作:(1)数据库worktask表新添是否有图片字 ...
- Oracle 实现 mysql 的 find_in_set 排序!
oracle 实现类似MYSQL的 find_in_set 排序,函数 decode: select * from tb_info_game where gameid in(23,20,19,26,1 ...
- mysql 分组内 排序
mysql 分组内 排序 类似于 sqlserver over partition by 因为mysql中木有sqlserver over partition by这个函数,要从sqlserver ...
- Mysql 内部默认排序
mysql默认的排序: https://forums.mysql.com/read.php?21,239471,239688#msg-239688 Do not depend on order whe ...
- Mysql order by 排序 varchar 类型数据
Mysql order by 排序 varchar 类型数据 varchar 类型字段排序, 会將数字当成字符串来处理. 排序规则一般是从左到右一位位来比较. +0之后 就转化成INT 类型排序 ...
- MySQL字符集与排序规则总结
字符集与排序规则概念 在数据库当中都有字符集和排序规则的概念, 很多开发人员甚至包括有些DBA都会将这个混淆,当然这个情况也有一些情有可原的原因.一来两者本来就是相辅相成,相互依赖关联: 另外一方 ...
- MySQL 多列排序
MySQL 基础篇 三范式 MySQL 军规 MySQL 配置 MySQL 用户管理和权限设置 MySQL 常用函数介绍 MySQL 字段类型介绍 MySQL 多列排序 MySQL 行转列 列转行 M ...
- 聊聊MySQL常用的4种主从复制架构
目录 一主多从复制架构 多级复制架构 双主(Dual Master)复制架构 多源(Multi-Source)复制架构 如何优化主从延迟问题? 复制的4中常见架构有一主多从复制架构.多级复制架构.双主 ...
随机推荐
- 【中秋国庆不断更】OpenHarmony组件内状态变量使用:@State装饰器
[中秋国庆不断更]OpenHarmony组件内状态变量使用:@State装饰器 @State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来.当状态改变时,UI会发生对 ...
- OpenHarmony 3.2 Beta多媒体系列——视频录制
一.简介 媒体子系统为开发者提供了媒体相关的很多功能,本文针对其中的视频录制功能做个详细的介绍.首先,我将通过媒体子系统提供的视频录制Test代码作为切入点,给大家梳理一下整个录制的流程. 二.目录 ...
- Agent内存马分析
什么是Java Agent 我们知道Java是一种强类型语言,在运行之前必须将其编译成.class字节码,然后再交给JVM处理运行.Java Agent就是一种能在不影响正常编译的前提下,修改Java ...
- ThinkPHP6.x 使用指南
PHP 版本:PHP 8.1.0 框架版本:ThinkPHP 6 编辑工具:PHPStorm 2021.3.3 系统环境:Windows 10 0x01 概述 (1)简介 ThinkPHP 框架简称 ...
- 墨水污染的一角qsnctfwp
题目附件 在图片中最直接的信息是电话号码,将号码输入到搜索引擎,可以得到该书的出版社为:高等教育出版社. 进入高等教育出版社官网 根据物料号前四位.版次时间.印次时间,在官网中进行图书查询. 结合字数 ...
- 重新整理数据结构与算法(c#系列)—— 树的前中后序遍历查找[十七]
前言 树的前中后序遍历 是根据前中后序的顺序来查找,找到了则弹出. 正文 节点模型: public class HeroNode { private int no; private string na ...
- 吴恩达机器学习课后作业ex1
题目大体意思就是输入的是某地的人口,输出的是某地方的收益. 题目及数据集下载: https://wwa.lanzous.com/b054sprza 密码:ba3w 大体模型如下图:现在X前边加一列值为 ...
- 加入自定义块对fashion_mnist数据集进行softmax分类
在之前,我们实现了使用torch自带的层对fashion_mnist数据集进行分类.这次,我们加入一个自己实现的block,实现一个四层的多层感知机进行softmax分类,作为对"自定义块& ...
- K8s场景下Logtail组件可观测方案升级-Logtail事件监控发布
简介: SLS针对Logtail本身以及Logtail的管控组件alibaba-log-controller,采用K8s事件的方式,将处理流程中的关键事件透出,从而让用户能够更清楚的感知其中发生的异常 ...
- 阿里云张新涛:连接产业上下游,构建XR协作生态
简介: 用交互技术辅以澎湃的算力带给大家最真实的"沉浸式体验" 2022年9月2日,在世界人工智能大会"区块新生 数字宇宙--元宇宙技术与生态合作"分论坛上,阿 ...