【MySQL】orderby/groupby出现Using filesort根因分析及优化

在日常的数据库运维中,我们可能会遇到一些看似难以理解的现象。比如两个SQL查询语句,仅仅在ORDER BY子句上略有不同,却造成了性能的天壤之别——一个飞速完成,一个则让数据库崩溃。今天就让我们围绕这个问题,深入剖析MySQL的查询优化机制。

Q1 - 能否自我介绍下?

嗨,大家好,我是 小 明 (小明java问道之路)互联网大厂后端研发专家,2022博客之星TOP3/博客专家/CSDN后端内容合伙人、InfoQ(极客时间)签约作者、阿里云签约博主、全网5万粉丝博主。

一个8年开发经验的老兵,专注于面试/后端/源码/架构/算法,擅长面试高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 

Q2 - 出现 Using filesort 问题分析?

  • 我们拿到两条SQL语句,第一条查询语句是:"WHERE time >= '2023-12-21 00:00:00' ORDER BY time ASC
  • 第二条查询语句是:"WHERE time >= '2023-12-21 00:00:00' ORDER BY id ASC“。

通过EXPLAIN命令对两条SQL进行分析后发现,在使用id作为排序字段时,MySQL使用了Using filesort 操作;但是在使用time作为排序字段时,却没有 Using filesort。而我们知道,Using filesort通常代表着磁盘排序,相较于内存排序,它的性能开销要大很多。

那么问题来了,既然id是主键,应该有更好的性能,为什么会导致 Using filesort 的出现呢?

Q3 - 问题原因是什么?

在我们的例子中,假设time字段的值是递增的,并且与id的增长趋势大致一致。那么在执行类似"WHERE time >='2023-12-21 00:00:00' ORDER BY time ASC"的查询时,MySQL可以通过time索引找到满足条件的第一个记录,然后顺序扫描后面的记录直到没有满足WHERE条件的记录为止。

在这个过程中,由于已经按照time字段的顺序读取记录,所以不需要额外的排序操作

但当我们改为"WHERE time >='2023-12-21 00:00:00' ORDER BY id ASC"时,就不能保证按id的顺序读取记录了。

因为虽然两个字段都是递增的,但并不能确保每个time值对应的id也是按顺序排列的。此时,MySQL查询优化器可能会选择扫描所有满足条件的记录,并把它们加载进入一个临时表进行排序,这样就产生了 Using filesort

Q4 - MySQL索引与查询优化器?

MySQL的索引可以提高查询速度,因为它们使得MySQL可以找到记录而无需扫描整个表。然而,索引并非万能的,它也会带来存储和管理的开销。所以,当MySQL选择执行计划时,会基于众多因素来考虑是否使用索引、使用哪种索引,以及如何使用索引。

NULL值和数据分布及唯一性都可以影响MySQL索引的使用效果。除此之外,MySQL的查询优化器还会根据查询条件和排序规则,选择最佳的索引进行操作。这就可能出现我们现在这个情况,即使id是主键,但如果在使用id进行排序时,不能有效利用索引,也可能产生 Using filesort 操作。

 

Q5 - 解决方案是什么?

  • 如果我们经常需要按照time和id排序的查询,一种解决方案是创建联合索引(time, id)。这样即使按照id排序,也能利用索引进行优化。因为对于联合索引来说,MySQL可以在满足time过滤条件的情况下,直接使用索引进行id的排序。
  • 可以尝试调整MySQL的sort_buffer_size参数。如果排序的数据量小于这个参数,那么MySQL可能会选择内存排序而非 Using filesort。需要注意的是,这个参数是每个连接独享的,设置得过大可能会浪费内存资源。

总结

理解MySQL索引的使用规则和查询优化器的工作原理,可以帮助我们更好地优化数据库性能,解决实际问题。同时,要明白没有最好的索引,只有最合适的索引。我们需要根据业务需求和实际数据分布,来选择和优化索引。

在本次的问题中,我们通过理解索引、排序以及查询优化器的工作原理,找出了导致问题的根源,并提出了相应的解决方案。

充分体现了,深入理解和掌握相关知识,对于我们解决实际问题的重要性。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

prometheus grafana linux服务器监控

文章目录 前传node-exporter安装配置promethues监控node节点grafana操作查看监控:外传 前传 prometheus grafana的安装使用:https://nanxiang.blog.csdn.net/article/details/135384541 本文说下监控nginx,prometheus grafana linux 安装配…

(NeRF学习)NeRF复现 win11

目录 一、获取源码二、环境三、准备数据集1.下载数据集方法一:官方命令方法二:官网下载数据集 2.修改配置 四、开始训练1.更改迭代次数2.开始训练方法一:方法二: 3.使用预训练模型 五、NeRF源码学习 一、获取源码 git clone http…

初识MySQL

一、什么是数据库 数据库(Database,简称DB):长期存放在计算机内,有组织、可共享的大量数据的集合,是一个数据“仓库”。 数据库的作用: 可以结构化存储大量的数据,方便检索和访问…

kubeadm开快速的搭建一个k8s集群

kubeadm开快速的搭建一个k8s集群 二进制适合大集群,50台以上主机 kubeadm更适合中小企业的业务集群。 master节点 20.0.0.92 docker kubelet kubeadm kubectl flannel node1 20.0.0. 94 docker kubelet kubeadm kubectl flanne node2 20.0.0.03 docker kubelet…

面试题:聊聊 SpringBoot 中的 SPI 机制

文章目录 简介Java SPI实现示例说明实现类1实现类2相关测试 源码分析Spring SPISpring 示例定义接口相关实现 相关测试类输出结果源码分析 总结 简介 SPI(Service Provider Interface)是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要用于框架…

HTTPS协议详解

目录 前言 一、HTTPS协议 1、加密是什么 2、为什么要加密 二、常见加密方式 1、对称加密 2、非对称加密 三、数据摘要与数据指纹 1、数据摘要 2、数据指纹 四、HTTPS加密策略探究 1、只使用对称加密 2、只使用非对称加密 3、双方都使用非对称加密 4、对称加密非…

开发个小破软件——网址导航,解压就能用

网址导航 网站导航也称链接目录,将网站地址或系统地址分类,以列表、图文等形式呈现,帮助快速找到需要的地址。 应用场景 高效查找:网址导航是很好的入口,通过分类清晰的网站推荐,可以迅速访问网站资源。…

SVN下载安装(服务器与客户端)

1.下载 服务器下载:Download | VisualSVN Server 客户端下载:自行查找 2. 服务器安装 双击执行 运行 下一步 同意下一步 下一步 选中安装目录 3. 客户端安装 双击执行 下一步 4. 服务器创建仓库 5. 服务器创建用户 6. 客户端获取资源 文件夹右键

微服务全链路灰度方案介绍

目录 一、单体架构下的服务发布 1.1 蓝绿发布 二、微服务架构下的服务发布 三、微服务场景下服务发布的问题 四、全链路灰度解决方案 4.1 物理环境隔离 4.2 逻辑环境隔离 4.3 全链路灰度方案实现技术 4.3.1 标签路由 4.3.2 节点打标 4.3.3 流量染色 4.3.4 分布式链路…

MyBatis源码分析(二):项目结构

目录 1、前言 2、代码统计 3、整体架构 3.1、基础支持层 3.1.1、反射模块 3.1.2、类型模块 3.1.3、日志模块 3.1.4、IO模块 3.1.5、解析器模块 3.1.6、数据源模块 3.1.7、缓存模块 3.1.8、Binding 模块 3.1.9、注解模块 3.1.10、异常模块 3.2、核心处理层 3.2.…

Pytorch简介

1.1 Pytorch的历史 PyTorch是一个由Facebook的人工智能研究团队开发的开源深度学习框架。在2016年发布后,PyTorch很快就因其易用性、灵活性和强大的功能而在科研社区中广受欢迎。下面我们将详细介绍PyTorch的发展历程。 在2016年,Facebook的AI研究团队…

【C++】Ubuntu编译filezilla client

在新版Ubuntu 22.04.3 LTS上编译filezilla client成功,shell命令如下: sudo apt-get install libfilezilla-dev libwxbase3.0-dev gnutls-dev libdbus-1-dev sudo apt-get install libwxgtk3.0-gtk3-dev sudo apt-get install libgtk-3-dev sudo apt-ge…

【GO语言卵细胞级别教程】01.GO基础知识

01.GO基础知识 目录 01.GO基础知识1.GO语言的发展历程2.发展历程3.Windowns安装4.VSCode配置5.基础语法5.1 第一段代码5.2 GO执行的流程5.3 语法规则5.4 代码风格5.5 学习网址 1.GO语言的发展历程 Go语言是谷歌公司于2007年开始开发的一种编程语言,由Robert Griese…

Python从入门到精通之元类

系列 Python从入门到精通之安装与快速入门-CSDN博客 Python从入门到精通之基本数据类型和变量-CSDN博客 Python从入门到精通之集合(List列表、Tuple元组、Dict字典、Set)-CSDN博客 Python从入门到精通之条件语句、循环语句和函数-CSDN博客 Python从…

STM32疑难杂症

1.keil的奇怪问题 创建的数组分配内存到0x10000000地址的时候,数据总是莫名其妙的出现问题,取消勾选就正常了 stm32f407内部有一个CCM内存,这部分内存只能由内核控制,任何外设都不能够进行访问。这样问题就来了,如果使…

ES6 class详解

✨ 专栏介绍 在现代Web开发中,JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性,还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言,JavaScript具有广泛的应用场景&#x…

基于SSM框架的宠物商城系统

开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 功能模块&…

基于引力搜索算法优化的Elman神经网络数据预测 - 附代码

基于引力搜索算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于引力搜索算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于引力搜索优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&…

(leetcode)判断字符是否唯一 -- 使用位图(位运算)

个人主页:Lei宝啊 愿所有美好如期而遇 目录 本题链接 输入描述 输出描述 算法分析 算法一:哈希表 算法二:位运算(位图) 解题源码 本题链接 力扣(LeetCode) 输入描述 接口:bool isUnique(st…

【AIGC风格prompt】风格类绘画风格的提示词技巧

风格类绘画风格的提示词展示 主题:首先需要确定绘画的主题,例如动物、自然景观、人物等。 描述:根据主题提供详细的描述,包括颜色、情感、场景等。 绘画细节:描述绘画中的细节,例如表情、纹理、光影等。 场…