SQL笔记 -- 查询优化

1. 关联查询优化

1.1 驱动表和被驱动表

对于内连接来说,优化器会根据用户的查询语句做优化,决定先查哪张表。先查询的那张表就是驱动表,反之就是被驱动表。而对于外连接来说,大多数情况用户指定的主表就是驱动表,但优化器也会视情况进行选择。

1.2 Simple Nested-Loop Join (简单嵌套循环连接)

从表A中取出一条数据,遍历表B,将匹配到的数据放到result… 以此类推,驱动表A中的每一条记录与被驱动表B的记录进行判断。可以看到这种方式效率是非常低的,以上述表A数据100条,表B数据1000条计算,则A*B=10万次。

1.3 Index Nested-Loop Join (索引嵌套循环连接)

其优化的思路主要是为了减少内存表数据的匹配次数,所以要求被驱动表上必须有索引才行。通过外层表匹配条件直接与内层表索引进行匹配,避免和内存表的每条记录去进行比较,这样极大的减少了对内存表的匹配次数。

驱动表中的每条记录通过被驱动表的索引进行访问,因为索引查询的成本是比较固定的,故mysql优化器都倾向于使用记录数少的表作为驱动表(外表)。

如果被驱动表加索引,效率是非常高的,但如果索引不是主键索引,所以还得进行一次回表查询。相比,被驱动表的索引是主键索引,效率会更高。

1.4 Block Nested-Loop Join(块嵌套循环连接)

其优化思路为一次性缓存多条数据,把参与查询的列缓存到Join Buffer 里,然后拿join buffer里的数据批量与内层表的数据进行匹配,从而减少了内层循环的次数(遍历一次内层表就可以批量匹配一次Join Buffer里面的外层表数据)。当不使用Index Nested-Loop Join的时候,默认使用Block Nested-Loop Join。

1.5 总结

(1)整体效率比较:INLJ > BNLJ > SNLJ

(2)永远用小结果集驱动大结果集(其本质就是减少外层循环的数据数量)(小的度量单位指的是表行数 * 每行大小)

(3)为被驱动表匹配的条件增加索引(减少内存表的循环匹配次数)

(4)增大join buffer size的大小(一次索引的数据越多,那么内层包的扫描次数就越少)

(5)减少驱动表不必要的字段查询(字段越少,join buffer所缓存的数据就越多)

(6)从MySQL的8.0.20版本开始将废弃BNLJ,因为从MySQL8.0.18版本开始就加入了hash join默认都会使用hash join

1.6 优化思路

  • 保证被驱动表的JOIN字段已经创建了索引
  • 需要JOIN 的字段,数据类型保持绝对一致。
  • LEFT JOIN 时,选择小表作为驱动表, 大表作为被驱动表 。减少外层循环的次数。
  • INNER JOIN 时,MySQL会自动将 小结果集的表选为驱动表 。选择相信MySQL优化策略。
  • 能够直接多表关联的尽量直接关联,不用子查询。(减少查询的趟数)
  • 不建议使用子查询,建议将子查询SQL拆开结合程序多次查询,或使用 JOIN 来代替子查询。

2. 子查询优化

子查询是 MySQL 的一项重要的功能,可以帮助我们通过一个 SQL 语句实现比较复杂的查询。但是,子查询的执行效率不高。原因:

① 执行子查询时,MySQL需要为内层查询语句的查询结果 建立一个临时表 ,然后外层查询语句从临时表 中查询记录。查询完毕后,再 撤销这些临时表 。这样会消耗过多的CPU和IO资源,产生大量的慢查询。

② 子查询的结果集存储的临时表,不论是内存临时表还是磁盘临时表都 不会存在索引 ,所以查询性能会 受到一定的影响。

③ 对于返回结果集比较大的子查询,其对查询性能的影响也就越大。

在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快 ,如果查询中使用索引的话,性能就会更好。

3. 排序优化

在MySQL中,支持两种排序方式,分别是FileSort和Index排序。Index 排序中,索引可以保证数据的有序性,不需要再进行排序,效率更高。FileSort 排序则一般在内存中进行排序,占用CPU较多。如果待排结果较大,会产生临时文件 I/O 到磁盘进行排序的情况,效率较低。

优化思路:

(1) SQL 中,可以在 WHERE 子句和 ORDER BY 子句中使用索引,目的是在 WHERE 子句中避免全表扫描 ,在 ORDER BY 子句 避免使用 FileSort 排序 。当然,某些情况下全表扫描,或者 FileSort 排序不一定比索引慢。但总的来说,我们还是要避免,以提高查询效率。

(2)尽量使用 Index 完成 ORDER BY 排序。如果 WHERE 和 ORDER BY 后面是相同的列就使用单索引列; 如果不同就使用联合索引。

(3)无法使用 Index 时,需要对 FileSort 方式进行调优。

4. GROUP BY优化

  • group by 使用索引的原则几乎跟order by一致 ,group by 即使没有过滤条件用到索引,也可以直接使用索引。
  • group by 先排序再分组,遵照索引建的最佳左前缀法则
  • 当无法使用索引列,增大 max_length_for_sort_data 和 sort_buffer_size 参数的设置
  • where效率高于having,能写在where限定的条件就不要写在having中了
  • 减少使用order by,和业务沟通能不排序就不排序,或将排序放到程序端去做。Order by、group by、distinct这些语句较为耗费CPU,数据库的CPU资源是极其宝贵的。
  • 包含了order by、group by、distinct这些查询的语句,where条件过滤出来的结果集请保持在1000行 以内,否则SQL会很慢。

5. 分页查询优化

优化思路一
在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他列内容。

优化思路二
该方案适用于主键自增的表,可以把Limit 查询转换成某个位置的查询 。例如:

--优化前
SELECT * FROM student LIMIT 2000000,10;
--优化后
SELECT * FROM student WHERE id > 2000000 LIMIT 10;

6. 优先使用覆盖索引

索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此它不必读取整个行。毕竟索引叶子节点存储了它们索引的数据;当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了满足查询结果的数据就叫做覆盖索引。

正因为覆盖索引包含了满足查询结果的所有数据,因此就可以省去回表的操作,从而大大提升效率。

7. 索引下推ICP

索引下推(Index Condition Pushdown, ICP)是MySQL 5.6中新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式。当使用索引条件下推是,EXPLAIN语句输出结果中Extra列内容显示为Using index condition。

索引下推就是指在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数来提高查询效率。

# 打开索引下推
SET optimizer_switch = 'index_condition_pushdown=on';# 关闭索引下推
SET optimizer_switch = 'index_condition_pushdown=off';
ICP的使用条件

(1)如果表的访问类型为 range 、 ref 、 eq_ref 或者 ref_or_null 可以使用ICP。
(2)ICP可以使用InnDB和MyISAM表,包括分区表InnoDB和MyISAM表
(3) 对于InnoDB表,ICP仅用于二级索引。ICP的目标是减少全行读取次数,从而减少I/O操作。
(4)当SQL使用覆盖索引时,不支持ICP优化方法。因为这种情况下使用ICP不会减少I/O。
5. 相关子查询的条件不能使用ICP

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

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

相关文章

Demo: 实现PDF加水印以及自定义水印样式

实现PDF加水印以及自定义水印样式 <template><div><button click"previewHandle">预览</button><button click"downFileHandle">下载</button><el-input v-model"watermarkText" /><el-input v-mo…

敏捷开发之Scrum

敏捷开发是什么 我们一般习惯用瀑布模型&#xff0c;它以文档为驱动&#xff0c;将软件生命周期划分为固定的六个基本活动&#xff0c;并且规定了它们自上而下、相互衔接的次序&#xff0c;如同瀑布流水&#xff0c;逐级下落。 那什么是敏捷开发呢&#xff1f; ​ 敏捷开发的核…

解决前端笔记本电脑屏幕显示缩放比例125%、150%对页面大小的影响问题

近期在工作中遇到一个问题&#xff0c;记录一下&#xff0c;在项目上线之后&#xff0c;遇到一个问题&#xff0c;即缩放到90%时&#xff0c;页面字体比默认的100%字体大&#xff0c;一开始毫无头绪&#xff0c;经过一番的Google...Google...Google....&#xff0c;终于找到了解…

代码随想录算法训练营第五天| 总结数组专题

数组&#xff1a;二分查找、双指针&#xff08;包括快慢指针&#xff09;、滑动窗口、模拟 链表&#xff1a;双指针、三指针、虚拟头指针、复杂指针操作画图明确每一步&#xff08;标好次序&#xff09; 数组 代码随想录总结的很好&#xff0c;如下图。我再结合自己的一些理解…

AI 的未来是开源的

想象一下&#xff0c;在未来&#xff0c;人工智能不会被锁在公司的金库里&#xff0c;而是由全球创新者社区一砖一瓦地在开放中构建的。协作&#xff0c;而不是竞争&#xff0c;推动进步&#xff0c;道德考虑与原始绩效同等重要。这不是科幻小说&#xff0c;而是人工智能发展核…

【PostgreSQL内核学习(二十四) —— (ALTER MATERIALIZED VIEW)】

ALTER MATERIALIZED VIEW 概述源码解析修改物化视图的属性和行为AlterTableStmt 结构体AlterTableMoveAllStmt 结构体 重命名RenameStmt 结构体 设置对象依赖于扩展AlterObjectDependsStmt 结构体 测试用例 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&…

C++I/O流——(4)格式化输入/输出(第二节)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 含泪播种的人一定能含笑收获&#xff…

73.网游逆向分析与插件开发-背包的获取-物品数据的初步数据分析

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;72.网游逆向分析与插件开发-背包的获取-项目需求与需求拆解-CSDN博客 然后首先找切入点&#xff1a; 通过药物来当切入点&#xff0c;药物比较好使用&#xff0c;然后鼠标放到药物上它有名字、种类、…

Java注解技术

1. 注解的简介 从JDK 5开始&#xff0c;Java增加了对元数据&#xff08;MetaData&#xff09;的支持&#xff0c;也就是注解&#xff08;Annotation&#xff09;。 注解就是代码里的特殊标记&#xff0c;这些标记可以在编译、类加载、运行时被读取&#xff0c;并执行相应的处…

【分布式技术】分布式存储ceph之RGW接口

目录 1、对象存储概念 2、创建 RGW 接口 //在管理节点创建一个 RGW 守护进程 #创建成功后默认情况下会自动创建一系列用于 RGW 的存储池 #默认情况下 RGW 监听 7480 号端口 //开启 httphttps &#xff0c;更改监听端口 #更改监听端口 ​ //创建 RadosGW 账户 …

【Go学习】macOS+IDEA运行golang项目,报command-line-arguments,undefined

写在前面的话&#xff1a;idea如何配置golang&#xff0c;自行百度 问题1&#xff1a;通过idea的terminal执行go test报错 ✘ xxxxxmacdeMacBook-Pro-3  /Volumes/mac/.../LearnGoWithTests/hello  go test go: go.mod file not found in current directory or any parent …

【LeetCode热题100】【子串】和为 K 的子数组

题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [1,…

Jet Brains 2023 开发者生态系统现状

一、前言 今天刷到Jet Brains官方发布了2023 开发者生态系统现状&#xff0c;这个相信大家都不陌生&#xff0c;我们的开发工具IDEA就是它旗下的。 分析的蛮不错的&#xff0c;今天整理一下&#xff0c;和大家一起分享。 有想法大家可以一起交流一下哈&#xff01; 有兴趣的…

unity SqLite读取行和列

项目文件 链接&#xff1a;https://pan.baidu.com/s/1BabHvQ-y0kX_w15r7UvIGQ 提取码&#xff1a;emsg –来自百度网盘超级会员V6的分享 using System.Collections; using System.Collections.Generic; using UnityEngine; using Mono.Data.Sqlite; using System; using Syste…

LeetCode刷题--- 买卖股票的最佳时机含冷冻期

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 ​​​​​​http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述动…

一个月学会Python,零基础入门数据分析

在数据分析领域&#xff0c;python是一个绕不开的知识和工具&#xff0c;如果不会用python就很难说自己会数据分析&#xff0c;但是最近很多想要入门数据分析的小白经常问我&#xff0c;Python怎么入门&#xff1f;Python虽然被称作是“最简洁的语言”&#xff0c;但是它终究还…

Jenkins 敏感信息实战指南

在 Jenkins 中&#xff0c;安全地管理敏感信息对于构建和部署过程至关重要。本实战指南将详细介绍如何添加凭据、使用 HashiCorp Vault 插件&#xff0c;并通过创建 Pipeline 脚本、在 shell 脚本中使用&#xff0c;以及在 Python 脚本中使用来管理敏感信息。 步骤 1: 添加凭据…

一文读懂——如何把网站改成HTTPS访问

HTTPS&#xff08;全称为Hyper Text Transfer Protocol Secure&#xff09;是一种在计算机网络上进行安全通信的协议&#xff0c;它通过SSL/TLS证书对传输数据进行加密&#xff0c;确保了用户与服务器之间信息交换的私密性和完整性。 获取SSL/TLS证书 选择证书类型&#xff1a…

构建高效数据生态:数据库、数据仓库、数据湖、大数据平台与数据中台解析_光点科技

在数字化的浪潮中&#xff0c;一套高效的数据管理系统是企业竞争力的核心。从传统的数据库到现代的数据中台&#xff0c;每一种技术都在数据的旅程中扮演着关键角色。本文将深入探讨数据库、数据仓库、数据湖、大数据平台以及数据中台的功能和价值&#xff0c;帮助您构建一个符…