MySQL 排序,分组,Limit的优化策略

news2024/11/25 15:45:05

目录

1. MySQL 中的两种排序方式

2. 排序优化策略

2.1 对排序字段添加索引

2.2 可以和WHERT字段创建联合索引

2.3 优化 FilerSort 排序方式

3. 分组优化策略

3.1 能WHERE不HAVING

3.2 减少ORDER BY,GROUP BY,DISTINCT

3.3 遵照最左前缀法则

4. Limit 优化策略


1. MySQL 中的两种排序方式

在MySQL中,主要支持两种排序方式,分别是 FileSort 和 Index。

Index:索引排序,就是我们给排序的字段添加了索引,因为索引本身就是有序的,所以我们在根据排序的时候就非常省时间了,不需要进行重排序,直接取出数据即可,效率很高。

FileSort:文件排序,在查询到数据之后,因为没有设置索引,所以CPU就需要在内存中进行排序,排好序之后再将数据进行返回,而且数据量如果较大,排序花费时间也会变长;并且,如果数据量非常大,内存中装不下,还需要多次IO操作,先读取一部分数据排序,再读取一部分数据排序,效率较低。

2. 排序优化策略

2.1 对排序字段添加索引

从上面两种排序方式不难看出,Index 索引排序明显是要比 FileSort 内存排序效率要高的,因此我们最好能够在排序字段上添加索引,这样在查询的时候就取出来的就是有序数据,省去了排序时间;

如下所示,我查询 employees 员工表并通过 salary 薪水字段排序,此时还没有给 salary 字段设置索引,查询到107条数据,花费 0.024秒;

 我现在给 salary 薪水字段设置一个普通索引,然后再去做一遍查询

 可以看到,再添加过索引之后,让然查询到了107条数据,时间缩短为0.017秒,可能同学们觉得没有什么差别,这只是因为数据量小的原因,只有一百多条记录,如果有上千条上万条数据,花费的时间一下子就拉开距离了。

2.2 可以和WHERT字段创建联合索引

在SQL语句中,排序通常也会出现WHERE过滤字段,在这种情况下,我们可以考虑给WHERE过滤字段和ORDER BY排序字段建立一个联合索引。如果二者是同一个字段,那就更完美了,就给这个字段建立独立索引;如果是两个字段,建立联合索引,但要注意WHERE过滤如果是范围查找,会导致联合索引中后续索引失效,那么即便设置了排序字段索引,也是用不上的。在设置联合索引时一定要注意满足最左前缀原则,保证索引能够生效。

如下,此时 department_id 和 salary 字段都有索引,但是没有联合索引,所以查询的时候只会用到 department_id 这个字段的索引,

此时我给 department_id 和 salary 建立联合索引再次查询 

查询得到相同的结果,使用联合索引时间0.017秒,比单独使用 department_id索引快了 0.02秒; 

2.3 优化 FilerSort 排序方式

有些时候,我们无法避免的会出现 FileSort 内存排序,其实内存排序有两种方式,分别是双路排序和单路排序。

双路排序:扫描两次磁盘,数据库会先将需要排序的字段IO加载到内存中进行排序,经过排序之后再根据排好序的字段再次IO将完整数据查询出来;

单路排序:数据库会一次性将全部数据加载到内存,然后进行排序,并且在IO的时候是顺序IO读取,读取过后再排序,比双路排序要好。因为双路排序在第二次IO读取数据的时候是根据排好序的顺序读取数据的,是随机IO,明显没有顺序IO要快。但如果数据量较大,就对内存要求较高,但现在内存技术发展迅速,内存已经不值钱了,所以通常建议采用单路排序

3. 分组优化策略

3.1 能WHERE不HAVING

HAVING也是一个过滤关键字,它后面可以使用聚合函数再次过滤,但是建议能在WHERE后面写的过滤条件就不要写在HAVING后面,WHERE过滤之后剩下的少量数据无论是排序还是分组都只会花费很少的时间,所以能WHERE过滤的数据就不要用HAVING。

3.2 减少ORDER BY,GROUP BY,DISTINCT

对于数据库而言,排序,分组,去重这些操作都是比较繁琐耗费资源的,如果将所有操作全部放在数据库中,非常容易出现慢查询,因此我们可以考虑将这些操作放在程序端去做,数据库查询到数据之后,使用程序代码进行排序分组去重;

3.3 遵照最左前缀法则

GROUP BY使用索引的规则几乎与ORDER BY一样,尽量遵循索引最左前缀原则;

4. Limit 优化策略

有些极端情况,如下,我取第十万条记录之后的十条记录,这种情况下数据库就会把所有的数据全部加载到内存中,分页排序之后只取第一万条记录之后的十条记录,做了大量的无用功。

SELECT * FROM employees ORDER BY employee_id LIMIT 10000,10;

那么我们就可以对上面的SQL做修改,直接使用WHERE过滤前一万条数据,从第10001条记录开始取。提高效率,但实际上这种情况很少发生,如果真的有有这种需求,建议直接将10000作为WHERE的一个过滤条件;

SELECT * FROM employees WHERE employee_id > 10000 LIMIT 10000,10;

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

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

相关文章

python 之 正则表达式模块re

文章目录 findall例子:特点和注意事项: match示例:match 对象的方法和属性:注意事项: search示例:match 对象的方法和属性:注意事项: split示例:参数说明:注意…

民宿酒店服务预约小程序的作用

民宿往往是旅游者们前往某个城市感受风情常住的地方,也因此在景区或特定地方,总是不乏大小民宿品牌,但除了市场高需求外,商家们所遇的痛点也不少: 1、获客引流难 民宿生意虽然需求量高,但各家品牌众多&am…

Unity meta的一些常见属性

Unity会项目文件夹中的每个文件分配一个同名后缀为.meta的文件。 我们可以将meta文件理解不同文件之间的桥梁,通过它引擎可以管理不同文件之间的依赖关系。 使用TXT文本文件打开之后,大致属性如下: 其中常用的属性有guid、 assetBundleName以…

大模型应用于数字人

大模型会改变整个软件行业, 其中具有代表性的产品之一是数字人, 那么,什么是数字人呢?数字人涉及了哪些关键技术呢?大模型对数字人的发展带来哪些影响呢? 1. 什么数字人? 数字人目前还缺乏一个相…

【图像分类】【深度学习】【Pytorch版本】AlexNet模型算法详解

【图像分类】【深度学习】【Pytorch版本】AlexNet模型算法详解 文章目录 【图像分类】【深度学习】【Pytorch版本】AlexNet模型算法详解前言AlexNet讲解卷积层的作用卷积过程特征图的大小计算公式Dropout的作用AlexNet模型结构 AlexNet Pytorch代码完整代码总结 前言 AlexNet是…

2.数制与编码

目录 一. 进位计数制 (1)二进制,八进制,十进制,十六进制 (2)二进制,八进制,十六进制的转换 (3)十进制转换成任意进制 (4&#xf…

linux命令screen解决client_loop: send disconnect: Broken pipe

一、SSH连接服务器,client_loop: send disconnect: Broken pipe 最近需要在服务器上运行一个需要跑很久的脚本,但ssh连接的远程服务器的命令窗口经常会报:client_loop: send disconnect: Broken pipe,这个错误是ssh 命令之后没有活…

电路布线问题动态规划详解(做题思路)

对于电路布线问题,想必学过动态规划的大家都很清除。今天就来讲解一下这个动态规划经典题目。 目录 问题描述输入分析最优子结构代码 问题描述 在一块电路板的上、下2端分别有n个接线柱。根据电路设计,要求用导 线(i,π(i))将上端接线柱与下端接线柱相…

家用电脑做服务器,本地服务器搭建,公网IP申请,路由器改桥接模式,拨号上网

先浇一盆冷水! 我不知道其他运营商是什么情况。联通的运营商公网IP端口 80、8080、443 都会被屏蔽掉,想要开放必须企业备案(个人不行)才可以。也就是说,只能通过其他端口进行showtime了。 需要哪些东西? 申…

【鸿蒙软件开发】ArkUI容器组件之Grid(网格布局)

文章目录 前言一、Grid1.1 子组件GridItem是什么子组件接口属性事件示例代码 1.2 接口参数 1.3 属性1.4 Grid的几种布局模式1.5 GridDirection枚举说明1.6事件ItemDragInfo对象说明 1.7 示例代码 总结 前言 Grid容器组件:网格容器,由“行”和“列”分割…

php对字符串中的特殊符号进行过滤的方法

1、使用htmlspecialchars函数&#xff1a;此函数将特殊字符转换为对应的HTML实体。示例代码如下&#xff1a; $str "<script>alert(XSS)</script>"; $filtered_str htmlspecialchars($str); echo $filtered_str; 输出&#xff1a; <script>ale…

四阶龙格库塔与元胞自动机

龙格库塔法参考&#xff1a; 【精选】四阶龙格库塔算法及matlab代码_四阶龙格库塔法matlab_漫道长歌行的博客-CSDN博客 龙格库塔算法 Runge Kutta Method及其Matlab代码_龙格库塔法matlab_Lzh_023016的博客-CSDN博客 元胞自动机参考&#xff1a; 元胞自动机&#xff1a;森林…

线性表(顺序表,单链表,双链表,循环链表,静态链表)

目录 1.线性表的定义1.几个重要的概念2.逻辑结构 2.线性表的基本操作3.顺序表&#xff08;线性表的顺序存储&#xff09;1.静态分配2.动态分配3.顺序表的特点4.顺序表的基本操作1.插入2.删除3.查找1.按位查找2.按值查找 4.链表&#xff08;线性表的链式存储&#xff09;1.单链表…

HackTheBox-Starting Point--Tier 1---Funnel

文章目录 一 题目二 实验过程三 利用SSH隧道3.1 本地端口转发 一 题目 Tags FTP、PostgreSQL、Reconnaissance、Tunneling、Password Spraying、Port Forwarding、Anonymous/Guest Access、Clear Text Credentials译文&#xff1a;FTP、PostgreSQL、侦察、隧道技术、密码喷洒…

【笔记】判断高电平,低电平和方波的几种方法

读取某一个上拉电平信号&#xff0c;它可能输出是低电平&#xff0c;可能是高电平&#xff0c;可能是方波&#xff0c;并且这个方波不知道频率何占空比&#xff0c;那么如何来通过程序来判断呢&#xff1f;高电平和低电平都好说&#xff0c;利用HAL库读取即可&#xff0c;如下&…

在云上jupylab(codelab)常用的shell命令

1、切换当前文件目录位置&#xff1a; %cd /project/train/ 2、删除目标文件夹和文件夹下面的内容&#xff0c;注意这个r是不能少的&#xff1a; !rm -r /project/train/src_repo/dataset 3、创建数据集相关文件夹 !mkdir /project/train/src_repo/dataset 4、复制指定…

Pytorch tensor 数据类型快速转换三种方法

目录 1 通用,简单&#xff0c;CPU/GPU tensor 数据类型转换 2 tensor.type()方法 CPU tensor 数据类型转换 GPU tensor 数据类型转换 3 tensor.to() 方法,CPU/GPU tensor 数据类型转换 1 通用,简单&#xff0c; CPU/GPU tensor 数据类型转换 tensor.double()&#xff1a;…

Educational Codeforces Round 157 (A--D)视频详解

Educational Codeforces Round 157 &#xff08;A--D&#xff09;视频详解 视频链接A题代码B题代码C题代码D题代码 视频链接 Educational Codeforces Round 157 &#xff08;A–D&#xff09;视频详解 A题代码 #include<bits/stdc.h> #define endl \n #define deb(x)…

高频SQL50题(基础版)-2

文章目录 主要内容一.SQL练习题1.577-员工奖金代码如下&#xff08;示例&#xff09;: 2.1280-学生们参加各科测试的次数代码如下&#xff08;示例&#xff09;: 3.570-至少有5名直接下属的经理代码如下&#xff08;示例&#xff09;: 4.1934-确认率代码如下&#xff08;示例&a…

C#,数值计算——偏微分方程,Relaxation的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class Relaxation { private Relaxation() { } public static void sor(double[,] a, double[,] b, double[,] c, double[,] d, double[,] e, double[,] f, double[,] u, double rjac) …