order by除了加索引,我们还可以怎么优化?

大家好,我是小趴菜,在平常业务中,排序是一个十分常见的需求,但是有些时候,因为一些操作导致我们排序的效率特别的低下,这时候我们通常会给排序的字段添加索引来解决,除了给排序字段添加索引,我们是否还有其它的优化手段呢?

order by原理

既然要优化,那么我们就必须要明白order by的底层原理是怎么样的

js 复制代码
select * from t_user where id > 10 order by age;
  • 1:MySql会根据where条件查询出所有符合条件的记录
  • 2:将查询的结果集放入sort_buffer中(排序内存)
  • 3:对中间结果集按照ORDER BY字段排序
  • 4:回表生成完整的结果集(如果需要)

以上就是我们在执行上述SQL要执行的步骤,也是ORDER BY的实现原理,那么我们要优化的地方有以下几点

优化点一:中间结果集

MySql首先会按照where条件查询出所有符合条件的记录,然后将结果集放入sort_buffer中,但是这里要注意的是,sort_buffer是有大小限制的,如果你的中间结果集大于这个sort_buffer的大小,那么这个中间集就不会放入内存中进行排序,而是放在硬盘中了。

我们都知道在内存中排序比在硬盘中排序效率是高出特别多的,我们可以使用 *show variables like '%sort_buffer_size%';*来查看sort_buffer的大小

所以当你的内存足够大的时候,我们可以适当调大sort_buffer的大小,让数据尽可能的在内存中排序,而不是进入到硬盘中

优化点二: 回表生成完整结果集

我们看最后一步,如果需要ORDER BY需要回表生成结果集,什么是回表呢?就是拿到这条记录的主键ID,到主键索引中找到整条记录。

比如说,我们一张表有一百多个字段,这时候我们需要把这一百多个字段都查询出来的,那么这时候,中间结果集可能不会有所有的字段,而是排序字段+主键,举个例子,如下,假设我们t_user表有一百多个字段

js 复制代码
select * from t_user where id > 10 order by age;

这时候首先会按照where条件查询出中间结果集,但是这时候的中间结果集可能不会有所有的字段,而是只有age+id二个字段,等排序结束以后,再拿主键回表查询整条记录,所以就造成了回表。

当要查询的字段小于这个阈值的时候,中间结果集就把所有字段都查出来,后续也就不需要回表了。但是当大于这个阈值的时候,就需要回表了

但是不能无脑的把这个值调大,来避免回表,还记得优化点一吗?? 如果你中间结果集太大,就不会在内存中进行排序,而是在硬盘中排序了。

总结

除了以上几点,我们最好是能使用到覆盖索引,这样就不用生成中间结果集中,可以直接输出结果了。

相关推荐
武子康8 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
大模型码小白8 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司9 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地10 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
憧憬成为web高手10 小时前
皮卡丘靶场速通--sql 2
数据库·sql·mybatis
IT_陈寒10 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端
段一凡-华北理工大学10 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
码事漫谈11 小时前
1999年的电商前夜和2026年的AI前夜 历史押韵但从不重复
后端
Conan在掘金11 小时前
鸿蒙报错速查:arkts-strict-typing Property does not exist on type 'object',object 装函数就炸,根因 + 真解法
后端
颜酱11 小时前
01 | 骨架搭建:FastAPI + Vue 跑通第一个 SSE 流式问答
前端·人工智能·后端