MySQL 索引之外的相关查询优化总结

在这之前先说明几个概念:
1、驱动表和被驱动表:驱动表是主表,被驱动表是从表、非驱动表。驱动表和被驱动表并非根据 from 后面表名的先后顺序而确定,而是根据 explain 语句查询得到的顺序确定;展示在前面的是驱动表,后面的是非驱动表。
2、关联查询的类型非为:内连接(inner join)、左外连接(left join)、右外连接(right join)、全外连接(full join);
一、关联查询优化
1、整体效率比较:INLJ>BNLJ>SNLJ(这些值在EXPLAIN语句中Extra字段展示)
2、永远用小结果集驱动大结果集(其本质就是减少外层循环的数据数量)(小的度量单位指的是 表行数"每行大小

#推荐
select t1.b,t2.* from t1 Istraight_join t2 on(t1.b=t2.b)where t2.id<=188;
#不推荐
select t1.b,t2.* from t2 straight_join t1 on (t1.b=t2.b) where t2.id<=108; 

3、为被驱动表匹配的条件增加索引(减少内层表的循环匹配次数)
4、增大join buffer size的大小(一次缓存的数据越多,那么内层包的扫表次数就越少).
5、减少驱动表不必要的字段査询(字段越少,join buffer 所缓存的数据就越多);
实践得到以下结论:
结论1:对于内连接来说,查询优化器可以决定谁来作为驱动表,谁作为被驱动表出现
结论2:对于内连接来讲,如果表的连接条件中只能有一个字段有索引,则有索引的字段所在的表会被作为被驱动表
结论3:对于内连接来说,在两个表的连接条件都存在索引的情况下,会选择小表作为驱动表。小表驱动大表
关联查询优化细节可参考视频教程上部和下部
二、子查询优化和排序优化(相关视频教程)
1、子查询是 MySQL 的一项重要的功能,可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作 ,能够帮助我们通过一个 SQL 语句实现比较复杂的查询。但是子查询的执行效率不高。原因如下:
(1) 执行子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表,然后外层查询语句从临时表中查询记录。查询完毕后,再撤销这些临时表。这样会消耗过多的 CPU 和 IO 资源,产生大量的慢查询。
(2) 子查询的结果集存储的临时表,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响。
(3) 对于返回结果集比较大的子查询,其对查询性能的影响也就越大。
在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快,如果查询中使用索引的话,性能就会更好。
2、在查询时不仅要在 WHERE 条件字段上加索引,还要在在 ORDER BY 字段上添加索引,因为在 MySQL 中,支持两种排序方式,分别是 FileSort 和 Index 排序。
◆ Index 排序中,索引可以保证数据的有序性,不需要再进行排序,效率更高。
◆ Filesort 排序则一般在内存中进行排序,占用 CPU 较多。如果待排结果较大,会产生临时文件 IO 到磁盘进行排序的情况,效率较低。
优化建议如下(这块的内容很详细,具体实践一定要看教程):
(1) SQL 中,可以在 WHERE 子句和 ORDER BY 子句中使用索引,目的是在 WHERE 子句中 避免全表扫描,在 ORDER BY 子句避免使用 FileSort 排序。当然,某些情况下全表扫描,或者 FileSort 排序不一定比索引慢。但总的来说,我们还是要避免,以提高查询效率。
(2) 尽量使用 Index 完成 ORDER BY 排序。如果 WHERE 和 ORDER BY 后面是相同的列就使用单索引列;如果不同就使用联合索引。
(3) 无法使用 Index 时,需要对 FileSort 方式进行调优。
三、GROUP BY优化和分页查询优化(相关视频教程)
1、group by 的优化策略主要包含以下六点
(1) group by 使用索引的原则几乎跟order by一致 ,group by 即使没有过滤条件用到索引,也可以直接使用索引。
(2) group by 先排序再分组,遵照索引建的最佳左前缀法则
(3) 当无法使用索引列,可以增大max_length_for_sort_data和sort_buffer_size参数的设置
(4) where效率高于having,能写在where限定的条件就不要写在having中了
(5) 减少使用 order by,和业务沟通能不排序就不排序,或将排序放到程序端去做。Order by、group by、distinct 这些语句较为耗费 CPU,数据库的CPU资源是极其宝贵的。
(6) 包含了order by、group by、distinct 这些查询的语句,where 条件过滤出来的结果集请保持在1000行以内,否则SQL会很慢。
2、一般分页查询时,通过创建覆盖索引能够比较好地提高性能。一个常见又非常头疼的问题就是 limit 2000000,10此时需要MySQL排序前2000010 记录,仅仅返回2000000-2000010 的记录,其他记录丢弃,查询排序的代价非常大。

EXPLAIN SELECT *FROM student LIMIT 2000000,10;

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

EXPLAIN SELECT * FROM student t,(SELECT id FROM student ORDER BY id LIMIT 2000000,10) a WHERE t.id = a.id;

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

EXPLAIN SELECT * FROM student WHERE id > 2000000 LIMIT 10;

四、覆盖索引的使用(相关视频教程)
1、什么是覆盖索引?
理解方式一:索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此它不必读取整个行。毕竟索引叶子节点存储了它们索引的数据;当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了满足查询结果的数据就叫做覆盖索引。
理解方式二:非聚簇复合索引的一种形式,它包括在查询里的SELECT、JOIN和WHERE子句用到的所有列(即建索引的字段正好是覆盖查询条件中所涉及的字段)。
简单说就是,索引列+主键包含SELECT 到 FROM之间查询的列。
2、索引覆盖的好处
(1) 避免Innodb表进行索引的二次查询(回表)
Innodb是以聚集索引的顺序来存储的,对于Innodb来说,二级索引在叶子节点中所保存的是行的主键信息,如果是用二级索引查询数据,在查找到相应的键值后,还需通过主键进行二次查询才能获取我们真实所需要的数据。在覆盖索引中,二级索引的键值中可以获取所要的数据,避免了对主键的二次査询 ,减少了IO操作,提升了查询效率。
(2) 可以把随机 IO 变成顺序 IO 加快查询效率
由于覆盖索引是按键值的顺序存储的,对于 IO 密集型的范围査找来说,对比随机从磁盘读取每一行的数据 IO 要少的多,因此利用覆盖索引在访问时也可以把磁盘的随机读取的 IO 转变成索引查找的顺序IO 。
由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。
3、索引覆盖的缺点
索引字段的维护总是有代价的。因此,在建立冗余索引来支持覆盖索引时就需要权衡考虑了。这是业务 DBA,或者称为业务数据架构师的工作。
五、索引条件下推(ICP)(相关视频教程)

select * from a where key > 'z' and key like '%a' 

以上查询语句在使用和不适用 ICP 两种场景如下
1、在不使用 ICP 索引扫描的过程:
storage层:只将满足index key条件的索引(key>‘z’)记录对应的整行记录取出,返回给server层,回表
server 层:对返回的数据,使用后面的where条件(key like ‘%a’)过滤,直至返回最后一行。
2、使用 ICP 扫描的过程:
storage层:首先将index key条件满足的索引(key>‘z’)记录区间确定,然后在索引上使用index filter进行(key like ‘%a’)过滤。将满足的index filter条件的索引记录才去回表取出整行记录返回server层。不满足index filter条件的索引记录丢弃,不回表、也不会返回server层。
server 层:对返回的数据,使用table filter条件做最后的过滤。
3、ICP 的开启/关闭
·默认情况下启用索引条件下推。可以通过设置系统变量 optimizer_switch 控制:index_condition_pushdown

#打开索引下推
SET optimizer switch='index condition pushdown=off':
#关闭索引下推
SET optimizer_switch='index_condition_pushdown=on';

4、ICP的使用条件
(1) 如果表访问的类型为 range、ref、eq_ref和ref_or_null 可以使用ICP
(2) ICP可以用于 InnoDB 和MyISAM 表,包括分区表 InnoDB和 MyISAM 表
(3) 对于 InnoDB 表,ICP 仅用于`二级索引’。ICP 的目标是减少全行读取次数,从而减少 /0 操作。
(4) 当SQL使用覆盖索引时,不支持ICP。为这种情况下使用ICP 不会减少 IO。
(5) 相关子查询的条件不能使用ICP
六、其他查询优化策略(相关视频教程)
1、EXISTS 和 IN 的区分
索引是个前提,其实选择与否还会要看表的大小。你可以将选择的标准理解为小表驱动大表。在这种方式下效率是最高的。
2、COUNT(*)、COUNT(1)与COUNT(具体字段)效率
前提:如果你要统计的是某个字段的非空数据行数,则另当别论,毕竟比较执行效率的前提是结果一样才可以。

环节1:COUNT(星)和COUNT(1)都是对所有结果进行COUNT,COUNT(星)和COUNT(1)本质上并没有区别(二者执行时间可能略有差别,不过你还是可以把它俩的执行效率看成是相等的)。如果有WHERE子句,则是对所有符合筛选条件的数据行进行统计;如果没有WHERE子句,则是对数据表的数据行数进行统计。

环节2:如果是MyISAM存储引擎,统计数据表的行数只需要O(1)的复杂度,这是因为每张MyISAM的数据表都有一个meta信息存储了row_count值,而一致性则是由表级锁来保证的。
如果是InnoDB存储引擎,因为InnoDB支持事务,采用行级锁和MVCC机制,所以无法像MyISAM一样,维护一个row_count变量,因此需要采用扫描全表,是O(n)的复杂度,进行循环+计数的方式来完成统计。

环节3:在InnoDB引擎中,如果采用COUNT(具体字段)来统计数据行数,要尽量采用二级索引。因为主键采用的索引是聚簇索引,聚簇索引包含的信息多,明显会大于二级索引(非聚簇索引)。对于COUNT(*)和COUNT(1)来说,它们不需要查找具体的行,只是统计行数,系统会自动采用占用空间更小的二级索引来进行统计。
如果有多个二级索引,会使用key_len小的二级索引进行扫描。当没有二级索引的时候,才会采用主键索引来进行统计。

3、关于SELECT(星)
在表查询中,建议明确字段,不要使用 * 作为查询的字段列表,推荐使用SELECT <字段列表> 查询。原因:
(1) MySQL 在解析的过程中,会通过查询数据字典将"*"按序转换成所有列名,这会大大的耗费资源和时间。
(2) 无法使用覆盖索引
4、LIMIT 1 对优化的影响
针对的是会扫描全表的 SQL 语句,如果你可以确定结果集只有一条,那么加上LIMIT 1的时候,当找到一条结果的时候就不会继续扫描了,这样会加快查询速度。
如果数据表已经对字段建立了唯一索引,那么可以通过索引进行查询,不会全表扫描的话,就不需要加上LIMIT 1了。
5、多使用 COMMIT
只要有可能,在程序中尽量多使用 COMMIT,这样程序的性能得到提高,需求也会因为 COMMIT 所释放的资源而减少。
COMMIT 所释放的资源:
(1) 回滚段上用于恢复数据的信息
(2) 被程序语句获得的锁
(3) redo / undo log buffer 中的空间
(4) 管理上述 3 种资源中的内部花费

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

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

相关文章

UI Toolkit系统学习

UI Toolkit 此文章用于学习UnityUI系统&#xff0c;手头的项目做完会来完善 官方文档 Unity上方菜单栏点击Window->UI Toolkit->Samples可以看UI Toolkit中的很多样例 使用 UI Toolkit 和 UI Builder 制作物品编辑器 在文件夹中右键->Create->UI Toolkit->Edi…

英特尔 Gaudi 加速辅助生成

随着模型规模的增长&#xff0c;生成式人工智能的实现需要大量的推理资源。这不仅增加了每次生成的成本&#xff0c;而且还增加了用于满足此类请求的功耗。因此&#xff0c;文本生成的推理优化对于降低延迟、基础设施成本以及功耗都至关重要&#xff0c;其可以改善用户体验并提…

leetCode-hot100-动态规划专题

动态规划 动态规划定义动态规划的核心思想动态规划的基本特征动态规划的基本思路例题322.零钱兑换53.最大子数组和72.编辑距离139.单词拆分62.不同路径63.不同路径Ⅱ64.最小路径和70.爬楼梯121.买卖股票的最佳时机152.乘积最大子数组 动态规划定义 动态规划&#xff08;Dynami…

【训练篇】MLU370-M8 完成 qwen1.5-7b-chat-lora训练及推理

文章目录 前言一、平台环境配置二、环境 or 模型准备1.模型下载2.环境准备2.1 modelscope2.2 transformers2.3 accelerate2.4 deepspeed2.5 peft2.6 环境代码修改 3训练代码准备4 代码修改 三&#xff0c;训练后推理验证四.推理效果展示1.微调前2.微调后 前言 本期我们采用魔塔…

【高考志愿】医学

目录 一、明确职业定位与兴趣 二、选择大学与专业 三、考虑身体条件 四、了解录取规则 五、考虑选科与成绩 六、注意志愿填报策略 七、关注就业前景 八、资深医生的建议 高考志愿填报学医时&#xff0c;考生需要综合考虑多个因素&#xff0c;确保自己能够做出明智的选择…

short s1 = 1; s1 = s1 + 1;有错吗

这个问题涉及到Java中的数据类型转换和赋值操作&#xff0c;是一个常见的面试题&#xff0c;用于考察应聘者对Java语言基础知识的掌握程度。 技术难点 数据类型转换&#xff1a;在Java中&#xff0c;基本数据类型之间的运算需要遵循类型转换规则。特别是当较小的数据类型&…

URLSearchParams: 浏览器中的查询字符串处理利器

一、 概述 在Web开发中&#xff0c;处理URL的查询字符串是一个常见任务。URLSearchParams API 提供了一种简单而强大的方法来处理Web URL的查询参数。它是一个内置的浏览器API&#xff0c;允许你以名称/值对的形式轻松地创建、读取、更新和删除查询参数。 二、URLSearchParam…

PostgreSQL的系统视图pg_stat_wal_receiver

PostgreSQL的系统视图pg_stat_wal_receiver 在 PostgreSQL 中&#xff0c;pg_stat_wal_receiver 视图提供了关于 WAL&#xff08;Write-Ahead Logging&#xff09;接收进程的统计信息。WAL 接收器是 PostgreSQL 集群中流复制的一部分&#xff0c;它在从节点中工作&#xff0c;…

distance delayed sound

distance delayed sound 在本章中&#xff0c;我们将讨论在游戏音频中使用距离延迟的重要性。我们将首先通过一个常见的例子——闪电和雷鸣&#xff0c;来展示这种重要性并解释距离延迟音频的基础知识。我们将讨论计算速度、距离和时间的数学和方程式&#xff0c;以确定距离延迟…

数据倾斜优化:Hive性能提升的核心

文章目录 1. 定义2. 数据倾斜2.1 Map2.2 Join2.3 Reduce 3. 写在最后 1. 定义 数据倾斜&#xff0c;也称为Data Skew&#xff0c;是在分布式计算环境中&#xff0c;由于数据分布不均匀导致某些任务处理的数据量远大于其他任务&#xff0c;从而形成性能瓶颈的现象。这种情况在H…

PotPlayer安装及高分辨率设置

第1步&#xff1a; 下载安装PotPlayer软件 PotPlayer链接&#xff1a;https://pan.baidu.com/s/1hW168dJrLBonUnpLI6F3qQ 提取码&#xff1a;z8xd 第2步&#xff1a; 下载插件&#xff0c;选择系统对应的位数进行运行&#xff0c;该文件不能删除&#xff0c;删除后将失效。 …

【强化学习的数学原理】课程笔记--2(贝尔曼最优公式,值迭代与策略迭代)

目录 贝尔曼最优公式最优 Policy求解贝尔曼最优公式求解最大 State Value v ∗ v^* v∗根据 v ∗ v^* v∗ 求解贪婪形式的最佳 Policy π ∗ \pi^* π∗一些证明过程 一些影响 π ∗ \pi^* π∗ 的因素如何让 π ∗ \pi^* π∗ 不 “绕弯路” γ \gamma γ 的影响reward 的…

2024/6/30周报

文章目录 摘要ABSTRACT文献阅读题目问题本文贡献方法LSTMTCN模型总体架构 实验实验结果 深度学习TCN-LSTM代码运行结果 总结 摘要 本周阅读了一篇关于TCN和LSTM进行光伏功率预测的文章&#xff0c;本文提出了一种利用LSTM-TCN预测光伏功率的新模型。它由长短期记忆和时间卷积网…

ThreadPoolExecutor基于ctl变量的声明周期管理

个人博客 ThreadPoolExecutor基于ctl变量的声明周期管理 | iwts’s blog 总集 想要完整了解下ThreadPoolExecutor&#xff1f;可以参考&#xff1a; 基于源码详解ThreadPoolExecutor实现原理 | iwts’s blog ctl字段的应用 线程池内部使用一个变量ctl维护两个值&#xff…

Vue异步DOM更新

Vue.js 是一个构建用户界面的渐进式框架&#xff0c;它采用了一种称为“响应式系统”的机制来跟踪数据的变化&#xff0c;并在数据变化时自动更新 DOM。然而&#xff0c;Vue 并不总是立即更新 DOM&#xff0c;而是会等待一个“tick”或“微任务”的完成&#xff0c;然后再进行批…

树莓派开发之文件传输

文章目录 一、简介使用U盘传输文件使用SD卡传输文件使用Xftp 7传输文件 二、 总结 一、简介 在树莓派开发中经常会用到文件传输&#xff0c;下面介绍几种树莓派文件传输的几种方法。 使用U盘传输文件 &#xff08;1&#xff09;复制所需传输文件到U盘 &#xff08;2&#…

C++:typeid4种cast转换

typeid typeid typeid是C标准库中提供的一种运算符&#xff0c;它用于获取类型的信息。它主要用于类型检查和动态类型识别。当你对一个变量或对象使用typeid运算符时&#xff0c;它会返回一个指向std::type_info类型的指针&#xff0c;这个信息包含了关于该类型名称、大小、基…

Pikachu靶场--Sql Inject

参考借鉴 pikachu靶场练习&#xff08;详细&#xff0c;完整&#xff0c;适合新手阅读&#xff09;-CSDN博客 数字型注入(post) 这种类型的SQL注入利用在用户输入处插入数值&#xff0c;而不是字符串。攻击者试图通过输入数字来修改SQL查询的逻辑&#xff0c;以执行恶意操作。…

如何在python中读取matlab输出的.mat文件

写在前面 经常会使用matlab处理数据&#xff0c;比如之前在进行空间滤波发现matlab自带的空间滤波函数。但是&#xff0c;由于后续使用python绘图更熟练一点&#xff0c;所以涉及到在python中读取matlab输出的文件&#xff0c;一般以.mat文件为主。下面测试了几种读取方式&…

jEasyUI 表单验证

jEasyUI 表单验证 jEasyUI 是一个基于 jQuery 的框架,用于创建交互式网页界面。它提供了一系列的组件,如布局、窗口、数据网格等,以及用于这些组件的皮肤和主题。在本文中,我们将重点讨论 jEasyUI 中的表单验证功能。 什么是表单验证? 表单验证是确保用户输入的数据符合…