架构师系列-MYSQL调优(六)- 排序优化

MySQL中的两种排序方式

  • 索引排序: 通过有序索引顺序扫描直接返回有序数据
  • 额外排序: 对返回的数据进行文件排序
  • ORDER BY优化的核心原则: 尽量减少额外的排序,通过索引直接返回有序数据。

索引排序 

因为索引的结构是B+树,索引中的数据是按照一定顺序进行排列的,所以在排序查询中如果能利用索引,就能避免额外的排序操作。EXPLAIN分析查询时,Extra显示为Using index。

比如查询条件是 where age = 21 order by name,那么查询过程就是会找到满足 age = 21 的记录,而符合这条的所有记录一定是按照 name 排序的,所以也不需要额外进行排序.

额外排序 

所有不是通过索引直接返回排序结果的操作都是Filesort排序,也就是说进行了额外的排序操作。EXPLAIN分析查询时,Extra显示为Using filesort。

按执行位置划分  

Sort_Buffer MySQL 为每个线程各维护了一块内存区域 sort_buffer ,用于进行排序。sort_buffer 的大小可以通过 sort_buffer_size 来设置。

mysql> show variables like '%sort_buffer_size%';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| sort_buffer_size        | 262144  |
+-------------------------+---------+mysql> select 262144 / 1024;
+---------------+
| 262144 / 1024 |
+---------------+
|      256.0000 |
+---------------+

 sort_Buffer_Size 并不是越大越好,由于是connection级的参数,过大的设置+高并发可能会耗尽系统内存资源。

Sort_Buffer + 临时文件

如果加载的记录字段总长度(可能是全字段也可能是 rowid排序的字段)小于 sort_buffer_size 便使用 sort_buffer 排序;如果超过则使用 sort_buffer + 临时文件进行排序。

临时文件种类:

临时表种类由参数 tmp_table_size 与临时表大小决定,如果内存临时表大小超过 tmp_table_size ,那么就会转成磁盘临时表。因为磁盘临时表在磁盘上,所以使用内存临时表的效率是大于磁盘临时表的。

按执行方式划分

执行方式是由 max_length_for_sort_data 参数与用于排序的单条记录字段长度决定的,如果用于排序的单条记录字段长度 <= max_length_for_sort_data ,就使用全字段排序;反之则使用 rowid 排序。

mysql> show variables like 'max_length_for_sort_data';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| max_length_for_sort_data | 1024  |
+--------------------------+-------+

 全字段排序

全字段排序就是将查询的所有字段全部加载进来进行排序。

优点:查询快,执行过程简单 缺点:需要的空间大。

select name,age,add from user where addr = '北京' order by name limit 1000; -- addr有索引

 

上面查询语句的执行流程:

  1. 初始化 sort_buffer,确定放入 name、age、addr 这3个字段。

  2. 从索引 addr 中找到第一个满足 addr=’北京’ 的主键ID(ID_x)。

  3. 到主键索引中找到 ID_x,取出整行,取 name、addr、age 3个字段的值,存入 sort_buffer。

  4. 从索引 addr 取下一个记录的主键ID。

  5. 重复3、4,直到 addr 值不满足条件。

  6. 对 sort_buffer 中的数据按照 name 做快速排序。

  7. 把排序结果中的前1000行返回给客户端。

 rowid排序

rowid 排序相对于全字段排序,不会把所有字段都放入sort_buffer。所以在sort buffer中进行排序之后还得回表查询。

缺点:会产生更多次数的回表查询,查询可能会慢一些。

优点:所需的空间更小

select name,age,add from user where addr = '北京' order by name limit 1000; -- addr有索引

假设 name、age、addr3个字段定义的总长度为36,而 max_length_for_sort_data = 16,就是单行的长度超了,MySQL认为单行太大,需要换一个算法。 放入 sort_buffer 的字段就会只有要排序的字段 name,和主键 id,那么排序的结果中就少了 addr 和 age,就需要回表了。

上面查询语句的执行流程:

  1. 初始化 sort_buffer,确定放入2个字段,name 和 id。
  2. 从索引 addr 中找到第一个满足addr=’北京’的主键ID(ID_x)。
  3. 到主键索引中取出整行,把 name、id 这2个字段放入 sort_buffer。
  4. 从索引 addr 取下一个记录的主键ID。
  5. 重复3、4,直到addr值不满足条件。
  6. 对 sort_buffer 中的数据按照 name 做快速排序。
  7. 取排序结果中的前1000行,并按照 id 的值到原表中取出 name、age、addr 3个字段的值返回给客户端。

总结

  • 如果 MySQL 认为内存足够大,会优先选择全字段排序,把需要的字段都放到 sort_buffer中, 这样排序后就会直接从内存里面返回查询结果了,不用再回到原表去取数据。
  • MySQL 的一个设计思想:如果内存够,就要多利用内存,尽量减少磁盘访问。 对于 InnoDB 表来说,rowid 排序会要求回表多造成磁盘读,因此不会被优先选择。

排序优化

添加索引 

-- 联合索引
ALTER TABLE employee ADD INDEX idx_name_age(NAME,age);-- 为薪资字段添加索引
ALTER TABLE employee ADD INDEX idx_salary(salary);
SHOW INDEX FROM employee; 

 场景1: 只查询用于排序的索引字段

只查询用于排序的 索引字段, 可以利用索引进行排序,最左原则

查询 name, age 两个字段, 并使用 nameage 行排序

EXPLAIN SELECT e.name, e.age FROM employee e ORDER BY e.name,e.age;

场景2: 排序字段在多个索引中,无法使用索引排序 

查询 name , salary 字段, 并使用 namesalary 排序

EXPLAIN SELECT e.name, e.salary FROM employee e ORDER BY e.name,e.salary;

 场景3: 只查询用于排序的索引字段和主键, 可以利用索引进行排序

查询 id , name , 使用 name 排序

EXPLAIN SELECT e.id, e.name FROM employee e ORDER BY e.name;

 场景4: 查询主键之外的没有添加索引的字段,不会利用索引排序

查询 dep_id ,使用 name 进行排序

EXPLAIN SELECT e.dep_id FROM employee e ORDER BY e.name;

 场景5: 排序字段顺序与索引列顺序不一致,无法利用索引排序

使用联合索引时, ORDER BY子句也要求, 排序字段顺序和联合索引列顺序匹配。

EXPLAIN SELECT e.name, e.age FROM employee e ORDER BY e.age,e.name;

场景6: where 条件是 范围查询时, 会使order by 索引 失效  

比如 添加一个条件 : age > 18 ,然后再根据 age 排序. 

EXPLAIN SELECT e.name, e.age FROM employee e WHERE e.age > 10 ORDER BY e.age;

 注意: ORDERBY子句不要求必须索引中第一列,没有仍然可以利用索引排序。但是有个前提条件,只有在等值过滤时才可以,范围查询时不行。

EXPLAIN SELECT e.name, e.age FROM employee e WHERE e.age = 18 ORDER BY e.age;

场景7: 升降序不一致,无法利用索引排序

ORDER BY排序字段要么全部正序排序,要么全部倒序排序,否则无法利用索引排序。

-- 升序
EXPLAIN SELECT e.name, e.age FROM employee e ORDER BY e.name , e.age ;-- 降序
EXPLAIN SELECT e.name, e.age FROM employee e ORDER BY e.name DESC, e.age DESC;

 

 name字段升序,age字段降序,索引失效

EXPLAIN SELECT e.name, e.age FROM employee e ORDER BY e.name, e.age DESC;

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

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

相关文章

janus架构学习

基础介绍 Janus 是由Meetecho设计和开发的开源、通用的基于SFU架构的WebRTC流媒体服务器&#xff0c;它支持在Linux的服务器或MacOS上的机器进行编译和安装。Janus 是使用C语言进行编写的&#xff0c;它的性能十分优秀。 架构 janus为sfu架构 模块结构图 模块说明 core模…

VR全景创业项目应该如何开展?未来有市场吗?

伴随着5G网络的发展&#xff0c;VR全景得到了众多的关注和提升。与此同时&#xff0c;各行各业都开始关注自身产业在互联网的展示效果&#xff0c;因为年轻一代的生活已经离不开互联网&#xff0c;而VR全景在互联网上的3D展示效果能给商家带来流量&#xff0c;提升营业额。 随着…

【Qt】.ui文件转.h文件

1、打开qt命令行 2、转换 uic -o ui.h mainwindow.ui

前端补充17(JS)

一、JS组成成分 JS的组成成分&#xff0c;由三部分组成 第一、ECMAScript&#xff1a;语法规则&#xff0c;如何定义变量&#xff0c;数据类型有哪些&#xff0c;如何转换数据类型&#xff0c;if判断 if-else while for for-in forEach do-while switch 数组 函数 对…

欧美助听器市场热门品牌盘点,国产爱可声备受青睐

近年来&#xff0c;随着中国技术的不断进步和品质的提升&#xff0c;国产助听器品牌爱可声在欧美市场备受瞩目。在欧美国家助听器市场&#xff0c;有许多热门品牌分别为&#xff1a;峰力、斯达克、瑞声达、爱可声等。这些品牌凭借其悠久的历史、先进的技术和高品质的产品&#…

monorepo搭建记录

最终文件效果 1、准备环境 npm pnpm 2、创建文件夹npm init vite // 名字可以为main&#xff08;自定义&#xff09; 创建主应用main npm init vite // 名字可以为main monorepo下创建文件夹web 创建辅助应用 例&#xff1a;react-demo&#xff0c;具体步骤&#xff1a;1、 cd…

HackMyVM-Hommie

目录 信息收集 arp nmap WEB web信息收集 dirsearch ftp tftp ssh连接 提权 系统信息收集 ssh提权 信息收集 arp ┌──(root㉿0x00)-[~/HackMyVM] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 08:00:27:77:ed:84, IPv4: 192.168.9.126 Starting arp-…

【svgwrite 库简介,附代码】如何将 .ttf 字体文件转化为 .svg 矢量图形?

当涉及到字体和矢量图形时&#xff0c;.ttf 和 .svg 是两种不同的文件格式&#xff1a; .ttf (TrueType Font)&#xff1a; .ttf 文件是一种常见的字体文件格式&#xff0c;用于存储 TrueType 字体。TrueType 是一种字体轮廓的标准&#xff0c;它使用贝塞尔曲线描述字形&…

IPEmotion 2024 R1支持通过USB2ETH适配器连接外部调制解调器

新发布的IPEmotion 2024 R1增加了很多新功能&#xff0c;其中最重要的新功能包括&#xff1a;支持使用USB2ETH适配器连接外部调制解调器&#xff1b;用户自定义的制冷剂可在IPEmotion PC中使用&#xff1b;支持使用XML或JSON文件为IPEconverter定义复杂的转换任务。 — 创新成果…

Springboot+Vue项目-基于Java+MySQL的网上点餐系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

定制自己的 AI 角色CustomChar;AI知识点和面试题;提高llama 3 的微调速度Unsloth

✨ 1: CustomChar 允许你创建和定制自己的 AI 角色 CustomChar 是一个开源项目&#xff0c;它允许你创建和定制自己的 AI 角色。无论是游戏中的角色&#xff0c;还是个人的虚拟助手&#xff08;比如电脑上的 JARVIS&#xff09;&#xff0c;甚至是在线教育体验中的虚拟朋友或…

数字旅游引领智慧化浪潮:科技创新重塑旅游体验,智慧服务打造旅游新高度

在科技飞速发展的今天&#xff0c;数字旅游正以其独特的魅力引领着智慧化浪潮&#xff0c;深刻改变着旅游行业的面貌。数字技术的广泛应用&#xff0c;不仅为旅游行业注入了新的活力&#xff0c;也极大地提升了旅游体验的品质。科技创新与智慧服务的融合&#xff0c;正推动着旅…

使用pytorch构建GAN模型的评估

本文为此系列的第六篇对GAN的评估&#xff0c;上一篇为Controllable GAN。文中使用训练好的分类模型的部分网络提取特征将真实分布与生成分布进行对比来评估模型的好坏&#xff0c;若有不懂的无监督知识点可以看本系列第一篇。 原理 1.评估模型的指标 一般来说&#xff0c;我们…

出海抢先看!必应bing广告投放的运营策略,助力企业获客爆单!

当今出海已成为众多企业拓展业务、寻求新增长点的重要战略&#xff0c;面对广阔的海外市场&#xff0c;选择合适的推广渠道对于提升品牌影响力、实现高效获客至关重要。必应Bing作为全球第二大搜索引擎&#xff0c;覆盖了大量高质量用户群体&#xff0c;尤其是在北美和欧洲市场…

HarmonyOS-静态库(SDK)的创建和使用

文章目录 一、静态库&#xff08;SDK&#xff09;二、创建静态库1.新建静态库模块2. 开发静态库内容3. 编译静态库 三、使用静态库1. 配置项目依赖2. 在应用中使用静态库3. 注意事项 四、打包错误1. library引用本地har包错误 一、静态库&#xff08;SDK&#xff09; 在Harmon…

IPEmotion轻松解决急停设备的控制与数据存储问题

一 背景 众所周知&#xff0c;急停操作在各种工业领域中都扮演着非常重要的角色。在一个个紧急情况下&#xff0c;及时采取急停操作可节省宝贵时间&#xff0c;避免人身伤害或设备损坏&#xff0c;降低安全风险&#xff0c;尤其是在新能源测试中&#xff0c;出于对高压电性能方…

Linux使用Libevent库实现一个网页服务器---C语言程序

Web服务器 这一个库的实现 其他的知识都是这一个专栏里面的文章 实际使用 编译的时候需要有一个libevent库 gcc httpserv.c -o httpserv -levent实际使用的时候需要指定端口以及共享的目录 ./httpserv 80 .这一个函数会吧这一个文件夹下面的所有文件共享出去 实际的效果, 这…

AI大模型重塑新媒体变现格局:智能写作技术助力腾飞!

文章目录 一、AI大模型&#xff1a;新媒体变革的引擎二、智能写作&#xff1a;内容生产的新范式三、精准推送&#xff1a;增强用户粘性的关键四、新媒体变现&#xff1a;插上AI翅膀的飞跃五、挑战与机遇并存&#xff1a;AI与新媒体的未来展望AI智能写作: 巧用AI大模型让新媒体变…

Python-GEE遥感云大数据分析、管理与可视化

原文链接&#xff1a;Python-GEE遥感云大数据分析、管理与可视化https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247601238&idx2&sn6b0557cf61451eaff65f025d648da869&chksmfa820db1cdf584a76de953b96519704177e6206d4ecd47a2f2fabbcac2f7ea619b0bce184…