MySQL基于规则的SQL优化

条件优化

  1. 移除不必要的括号

  2. 常量传递

这个表达式和其他涉及列a的表达式使⽤AND连接起来时,可以将其他表达式中的a的值替换为5,⽐如这样:
a = 5 AND b > a
就可以被转换为:
a = 5 AND b > 5

  1. 等值传递

a = b and b = c and c = 5
这个表达式可以被简化为:
a = 5 and b = 5 and c = 5

  1. 移除没有用的条件

(a < 1 and b = b) OR (a = 6 OR 5 != 5)
很明显,b = b这个表达式永远为TRUE,5 != 5这个表达式永远为FALSE,所以简化后的表达式就是这样的:
(a < 1 and TRUE) OR (a = 6 OR FALSE)
可以继续被简化为
a < 1 OR a = 6

  1. 表达式计算

在查询开始执⾏之前,如果表达式中只包含常量的话,它的值会被先计算出来,⽐如这个:
a = 5 + 1
因为5 + 1这个表达式只包含常量,所以就会被化简成:
a = 6
但是这⾥需要注意的是,如果某个列并不是以单独的形式作为表达式的操作数时,⽐如出现在函数中,出现在某个更复杂表达式中,就像这样:
ABS(a) > 5
或者:
-a < -8

  1. HAVING子句和WHERE子句的合并

如果查询语句中没有出现诸如SUM、MAX等等的聚集函数以及GROUP BY⼦句,优化器就把HAVING⼦句和WHERE⼦句合并起来。

  1. 常量表检测

查询的表中⼀条记录没有,或者只有⼀条记录。
使⽤主键等值匹配或者唯⼀⼆级索引列等值匹配作为搜索条件来查询某个表。

外连接消除

子查询优化

子查询语法

  • SELECT子句中
    SELECT	(SELECT	m1	FROM	t1	LIMIT	1);
    
  • 在FROM子句中
    SELECT	m,	n	FROM	(SELECT	m2	+	1	AS	m,	n2	AS	n	FROM	t2	WHERE	m2	>	2)	AS	t;
    
  • 在WHERE或ON子句中的表达式
    SELECT	*	FROM	t1	WHERE	m1	IN	(SELECT	m2	FROM	t2);
    
  • 在ORDER BY子句中
  • GROUP BY子句中

按返回的结果集区分⼦查询

  • 标量⼦查询
    那些只返回⼀个单⼀值的⼦查询称之为标量⼦查询
    SELECT	*	FROM	t1	WHERE	m1	=	(SELECT	MIN(m2)	FROM	t2);
    
  • ⾏⼦查询
    就是返回⼀条记录的⼦查询,不过这条记录需要包含多个列(只包含⼀个列就成了标量⼦查询了)。
    SELECT	*	FROM	t1	WHERE	(m1,	n1)	=	(SELECT	m2,	n2	FROM	t2	LIMIT	1);
    
  • 列⼦查询
    查询出⼀个列的数据喽,不过这个列的数据需要包含多条记录(只包含⼀条记录就成了标量⼦查询了)
    SELECT	*	FROM	t1	WHERE	m1	IN	(SELECT	m2	FROM	t2);
    
  • 表⼦查询
    就是⼦查询的结果既包含很多条记录,⼜包含很多个列
    SELECT	*	FROM	t1	WHERE	(m1,	n1)	IN	(SELECT	m2,	n2	FROM	t2);
    

按与外层查询关系来区分⼦查询

  • 不相关⼦查询
  • 相关⼦查询
    SELECT	*	FROM	t1	WHERE	m1	IN	(SELECT	m2	FROM	t2	WHERE	n1	=	n2);
    

⼦查询在布尔表达式中的使⽤

  • 使⽤=、>、<、>=、<=、<>、!=、<=>作为布尔表达式的操作符
  • [NOT] IN/ANY/SOME/ALL⼦查询
  • EXISTS⼦查询

⼦查询在MySQL中是怎么执⾏的

标量子查询、行子查询的执行方式
  • SELECT⼦句中,我们前边说过的在查询列表中的⼦查询必须是标量⼦查询。

  • ⼦查询使⽤=、>、<、>=、<=、<>、!=、<=>等操作符和某个操作数组成⼀个布尔表达式,这样的⼦查询必须是标量⼦查询或者⾏⼦查询。
    对于上述两种场景中的不相关标量⼦查询或者⾏⼦查询来说,它们的执⾏⽅式是简单的,⽐⽅说下边这个查询语句:

    SELECT	*	FROM	s1 WHERE	key1	=	(SELECT	common_field	FROM	s2	WHERE	key3	=	'a'	LIMIT	1);
    
  • 先单独执⾏(SELECT common_field FROM s2 WHERE key3 = ‘a’ LIMIT 1)这个⼦查询。

  • 然后在将上⼀步⼦查询得到的结果当作外层查询的参数再执⾏外层查询SELECT * FROM s1 WHERE key1 = …。

对于相关的标量⼦查询或者⾏⼦查询来说,⽐如下边这个查询:

SELECT * FROM s1 WHERE key1 = (SELECT common_field FROM s2	WHERE s1.key3 = s2.key3	LIMIT 1);
  • 先从外层查询中获取⼀条记录,本例中也就是先从s1表中获取⼀条记录。
  • 然后从上⼀步骤中获取的那条记录中找出⼦查询中涉及到的值,本例中就是从s1表中获取的那条记录中找出s1.key3列的值,然后执⾏⼦查询。
  • 最后根据⼦查询的查询结果来检测外层查询WHERE⼦句的条件是否成⽴,如果成⽴,就把外层查询的那条记录加⼊到结果集,否则就丢弃。
  • 再次执⾏第⼀步,获取第⼆条外层查询中的记录,依次类推

IN⼦查询优化

物化表的提出

对于不相关的IN⼦查询,⽐如这样:

SELECT	*	FROM	s1
   	WHERE	key1	IN	(SELECT	common_field	FROM	s2	WHERE	key3	=	'a');

不直接将不相关⼦查询的结果集当作外层查询的参数,⽽是将该结果集写⼊⼀个临时表⾥。

  • 临时表的列就是⼦查询结果集中的列。
  • 写⼊临时表的记录会被去重。
  • ⼀般情况下⼦查询结果集不会⼤的离谱,所以会为它建⽴基于内存的使⽤Memory存储引擎的临时表,⽽且会为该表建⽴哈希索引。如果⼦查询的结果集⾮常⼤,超过了系统变量tmp_table_size或者max_heap_table_size,临时表会转⽽使⽤基于磁盘的存储引擎来保存结果集中的记录,索引类型也对应转变为B+树索引。
物化表转连接

将子查询的结果集转化为雾化表(materialized_table)后,再将子查询转连接查询。

	SELECT s1.* FROM s1 INNER JOIN materialized_table ON key1 = m_val;
⼦查询转换为semi-join(半连接)

将之前的sql转化一下成半联动

	SELECT	s1.*	FROM	s1	SEMI	JOIN	s2 ON	s1.key1	=	s2.common_field WHERE	key3	=	'a';

半联动的实现方式:

  • Table pullout (⼦查询中的表上拉)
    ⼦查询的查询列表处只有主键或者唯⼀索引列时,可以直接把⼦查询中的表上拉到外层查询的FROM⼦句中
###原始sql
SELECT	*	FROM	s1
   	WHERE	key2	IN	(SELECT	key2	FROM	s2	WHERE	key3	=	'a');
### 优化后
SELECT	s1.*	FROM	s1	INNER	JOIN	s2 ON	s1.key2	=	s2.key2 WHERE	s2.key3	=	'a';
semi-join的适⽤条件
  • 该⼦查询必须是和IN语句组成的布尔表达式,并且在外层查询的WHERE或者ON⼦句中出现。
  • 外层查询也可以有其他的搜索条件,只不过和IN⼦查询的搜索条件必须使⽤AND连接起来。
  • 该⼦查询必须是⼀个单⼀的查询,不能是由若⼲查询由UNION连接起来的形式。
  • 该⼦查询不能包含GROUP BY或者HAVING语句或者聚集函数。

对于⼀些不能将⼦查询转位semi-join的情况,典型的⽐如下边这⼏种:

  • 外层查询的WHERE条件中有其他搜索条件与IN⼦查询组成的布尔表达式使⽤OR连接起来
  • 使⽤NOT IN⽽不是IN的情况
  • 在SELECT⼦句中的IN⼦查询的情况
  • ⼦查询中包含GROUP BY、HAVING或者聚集函数的情况
  • ⼦查询中包含UNION的情况
  • 对于不相关⼦查询来说,可以尝试把它们物化之后再参与查询
  • 不管⼦查询是相关的还是不相关的,都可以把IN⼦查询尝试专为EXISTS⼦查询
双路排序与单路排序

单路排序:一次取出所有字段进行排序,内存不够用的时候就会使用磁盘
双路排序:取出排序字段进行排序,排序完成后再次回表查询所需要的其他字段。

受:sort_buffer_size和max_length_for_sort_data影响

groupby与orderby在索引使用上的区别?
  • groupby没有过滤条件,也可以使用索引。order by必须要有过滤条件才能使用上索引。
  • groupby

MySQL超大分页该怎么处理

  • 分页语句解释

    select id, name from user limit offset,N; #在 使用的时候并不是跳过 offset 行,而是取offset +N 行,然后返回放弃前 offset,返回N行。

  • 通过索引优化
    • 如果是自增可以select name from user where id > XX limit N;
    • 延迟关联 # select a.* from user a,(select id from user where LIMIT offset ,N) b where a.id = b.id;
    • 需要order by时
      • 增加筛选条件,避免全表排序
      • 减少select 字段
      • 优化相关参数避免filesort
  • 可以使用缓存前几页的查询效率。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程大纲: 第1课 数据库与关系代数 综述数据库、关系代数、查询优化技术 综述数据库调优技术 预计时间1小时 第2课 数据库查询优化技术总揽 综述查询优化技术范围,包括查询重用、查询重写规则、查询算法优化、并行查询优化等 综述逻辑查询优化,包括子查询的优化、视图重写、等价谓词重写、条件化简、连接消除、非SPJ的优化等 综述逻辑物理优化,包括单表扫描算法、两表连接算法、多表连接算法、基于代价的算法等 初步理解MySQL的查询执行计划。 预计时间1小时 第3课 查询优化技术理论与MySQL实践(一)------子查询的优化(一) 第4课 查询优化技术理论与MySQL实践(二)------子查询的优化(二) 从理论看,子查询包括的内容和范围,建立清晰的概念 从实践看,MySQL的子查询优化技术的内容和范围,明确掌握子查询优化手段 预计时间2小时,每小时一个课程段(子查询是SQL查询优化的重点内容,务必掌握好) 第5课 查询优化技术理论与MySQL实践(三)------视图重写与等价谓词重写 什么是视图重写?哪些类型的视图可以被优化MySQL是怎么优化视图的?从而明白在MySQL中怎么写与视图相关的查询语句才能有好的效果? 什么是等价谓词重写?MySQL中怎么写WHERE子句有利于提高查询效率? 预计时间1小时 第6课 查询优化技术理论与MySQL实践(四)------条件化简 什么是条件化简?MySQL中对什么样的条件自动进行优化?如何写出可利用索引的条件语句? 预计时间1小时 第7课 查询优化技术理论与MySQL实践(五)------外连接消除、嵌套连接消除与连接消除 连接方式有些什么类型?不同类型的连接又是怎么优化的?外连接优化的条件是什么?MySQL中怎么写出可优化的连接语句?MySQL是否支持嵌套连接消除?MySQL是否支持连接消除?MySQL中书写SQL连接查询语句时的优化技巧。 预计时间1小时 第8课 查询优化技术理论与MySQL实践(六)------数据库的约束规则与语义优化 数据库的参照完整性(CHECKt NULL等)。什么是语义优化MySQL是否支持语义优化?怎么利用语义优化的思路人工进行SQL语句的优化? 预计时间1小时 第9课 查询优化技术理论与MySQL实践(七)------非SPJ的优化 什么是非SPJ优化? 从理论看,GROUP BY、ORDER BY、LIMIT、DISTINCT等怎么被优化MySQL中:GROUP BY是怎么优化的?ORDER BY是怎么被优化?LIMIT是怎么被优化?DISTINCT是怎么被优化? 非SPJ优化与索引的关系。 预计时间1小时 第10课 MySQL物理查询优化技术概述 从理论看,物理查询优化技术的范围。 从MySQL实践看,怎么利用物理查询优化技术对SQL查询语句调优? 本节预计会承接第9课的部分内容。 预计时间1小时 第11课 MySQL索引的利用、优化MySQL索引的角度出发,看各种SQL查询语句的优化怎么进行?(以前都是从语句的角度看怎么优化,现在站在索引的角度去总结SQL查询语句的优化) 预计时间1小时 第12课 表扫描与连接算法与MySQL多表连接优化实践 MySQL的单表扫描算法。MySQL的两表连接算法。MySQL的多表连接算法。 MySQL的多表连接的优化技巧。 预计时间1小时 第13课 查询优化的综合实例(一)------TPCH实践(一) 第14课 查询优化的综合实例(一)------TPCH实践(二) 以TPC-H国际标准的22条查询语句为实例,综合前面课程的内容,把所学的知识用于实践,进行综合的实战演练。 预计时间2小时(每个课时为1个小时) 第15课 关系代数对于数据库的查询优化的指导意义------查询优化技术总结 再次回到理论,从理论的高度总结关系代数理论与MySQL查询优化实践的关系。真正认识、掌握MySQL的查询优化技术,大步流星步入查询优化的高手之列。
├─新版MySQL DBA 课件ppt │ 第一课数据库介绍篇.pdf │ 第七课MySQL数据库设计.pdf │ 第三十一课percona-toolkits 的实战及自动化.pdf │ 第三课MySQL授权认证.pdf │ 第九课MySQL字符集.pdf │ 第二十一课MySQL常见错误-converted.pdf │ 第二十课MySQL索引和调优.pdf │ 第二课MySQL入门介绍.pdf │ 第五课MySQL常用函数介绍.pdf │ 第八课InnoDB内核.pdf │ 第六课SQL高级应用.pdf │ 第十一课MySQL表分区8.0.pdf │ 第十七课Elasticsearch分享-张亚V4.pdf │ 第十三课MySQL5.7高可用架构之Mycat.pdf │ 第十三课MySQL8.0高可用架构之Mycat.pdf │ 第十九课MySQL备份和恢复.pdf │ 第十二课MySQL5.7复制.pdf │ 第十二课MySQL8.0复制.pdf │ 第十五课MySQL8.0高可用架构之MHA和MMM.pdf │ 第十五课MySQL高可用架构之MHA和MMM.pdf │ 第十八课mongo分享-张亚V1.pdf │ 第十六课Redis分享-张亚V2.pdf │ 第十四课MySQL8.0高可用架构之Atlas.pdf │ 第十课MySQL8.0锁机制和事务.pdf │ 第十课MySQL锁机制和事务.pdf │ 第四课SQL基础语法.pdf │ ├─新版MySQL DBA综合实战班 第01天 │ 0_MySQL高级DBA公开课视频.avi │ 1_数据库通用知识介绍.avi │ 2_MySQL8常规安装.avi │ 3_MySQL8非常规安装.avi │ 4_MySQL8常见客户端和启动相关参数.avi │ ├─新版MySQL DBA综合实战班 第02天 │ 10_MySQL Update课堂练习.mp4 │ 1_课后作业讲解.mp4 │ 2_MySQL权限系统介绍.mp4 │ 3_MySQL授权用户和权限回收.mp4 │ 4_MySQL8新的密码认证方式和客户端链接.mp4 │ 5_MySQL Create命令.mp4 │ 6_MySQL CreateTable命令.mp4 │ 7_课堂练习1.mp4 │ 8_MySQL Insert命令.mp4 │ 9_MySQL Insert课堂练习和Update命令.mp4 │ ├─新版MySQL DBA综合实战班 第03天 │ 1_课堂作业讲解.mp4 │ 2_MySQL Delete语法讲解.mp4 │ 3_MySQL Select语法讲解.mp4 │ 4_MySQL Select多表连接讲解.mp4 │ 5_MySQL其他常用命令讲解.mp4 │ 6_MySQL操作符和常用函数.mp4 │ 7_MySQL常用字符串和日期函数.mp4 │ delete.txt │ MySQL高级DBA大作业1.docx │ 作业.docx │ ├─新版MySQL DBA综合实战班 第04天 │ 1_课后作业讲解.mp4 │ 2_SQL课堂强化练习1.mp4 │ 3_SQL课堂强化练习2.mp4 │ 4_存储过程函数概念和创建讲解.mp4 │ 5_存储过程函数流程控制语句讲解.mp4 │ ├─新版MySQL DBA综合实战班 第05天 │ 1_课后作业讲解.mp4 │ 2_MySQL游标讲解.mp4 │ 3_MySQL触发器.mp4 │ 4_MySQL触发器课堂强化练习.mp4 │ 5_MySQL数字和时间类型.mp4 │ 6_MySQL字符串类型.mp4 │ 7_MySQL存储引擎.mp4 │ 8_MySQL第三范式设计讲解.mp4 │ 9_MySQL数据库设计工具.mp4 │ ├─新版MySQL DBA综合实战班 第06天 │ 1_课堂作业讲解.mp4 │ 2_InnoDB内核之事务和多版本控制.mp4 │ 3_InnoDB底层文件存储和体系结构.mp4 │ 4_InnoDB体系结构.mp4 │ 5_InnoDB存储引擎配置.mp4 │ 6_InnoDB统计资料和其他配置.mp4 │ 7_InnoDB锁原理和锁等待问题定位.mp4 │ ├─新版MySQL DBA综合实战班 第07天 │ 1_课后作业讲解.mp4 │ 2_MySQL锁机制原理讲解.mp4 │ 3_MySQL锁相关参数设置.mp4 │ 4_InnoDB事务隔离级别详解.mp4 │ 5_InnoDB死锁发生原理和规避.mp4 │ 6_MySQL字符集和排序规则.mp4 │ 作业.docx │ 锁等待分析.txt │ ├─新版MySQL DBA综合实战班 第08天 │ 1_课堂作业讲解.mp4 │ 2_MySQL乱码原理讲解.mp4 │ 3_MySQL排序规则权重.mp4 │ 4_MySQL字符集空间消耗.mp4 │ 5_MySQL表分区介绍和优势.mp4 │ 6_MySQL表分区类型.mp4 │ 7_MySQL字表分区和NULL值特殊处理.mp4 │ 8_MySQL表分区管理.mp4 │ 作业.docx │ 作业及答案.docx │ ├─新版MySQL DBA综合实战班 第09天 │ 1_课堂作业讲解.mp4 │ 2_MySQL复制原理.mp4 │ 3_MySQL传统复制原理和搭建.mp4 │ 4_MySQL复制搭建part2.mp4 │ 5_MySQL复制相关参数.mp4 │ 6_MySQL复制状态和延迟复制.mp4 │ 7_MySQL半同步复制.mp4 │ 作业.docx │ ├─新版MySQL DBA综合实战班 第10天 │ │ 1_课后作业讲解.mp4 │ │ 2_MySQL传统复制手动切换和GTID复制原理及切换.mp4 │ │ 3_Mycat原理和schema配置讲解.mp4 │ │ 4_Mycat schema配置讲解.mp4 │ │ 5_Mycat企业高可用配置.mp4 │ │ 作业.docx │ │ │ └─MySQL DBA 课堂命令-复制和Mycat │ mysql-master.log │ mysql-master2.log │ mysql-mycat.log │ mysql-slave1.log │ mysql-slave2.log │ ├─新版MySQL DBA综合实战班 第11天 │ │ 1_课后作业讲解.mp4 │ │ 2_MyCat分库分表原理和常见方法.mp4 │ │ 3_MyCat管理操作.mp4 │ │ 4_Atlas配置和读写分离实现.mp4 │ │ 5_Atlas分库分表实现.mp4 │ │ 6_MHA搭建和故障切换原理剖析.mp4 │ │ │ └─MySQL DBA_课堂命令-Mycat和Atlas和MHA │ mysql-master.log │ mysql-mycat.log │ mysql-slave1.log │ mysql-slave2.log │ ├─新版MySQL DBA综合实战班 第12天 │ 01ES介绍.docx │ 01es介绍.mp4 │ 01redis介绍.mp4 │ 02es增删改查操作命令.mp4 │ 02ES的功能适用场景以及特点介绍.docx │ 02redis应用场景.mp4 │ 03ES的核心概念.docx │ 03redis单实例安装.mp4 │ 03集群分片副本操作.mp4 │ 04es集群运维.mp4 │ 04redis数据类型操作.mp4 │ 04安装search-guard.docx │ 05redis主从和哨兵操作.mp4 │ 06reids集群创建收缩扩容.mp4 │ 07redis运维工具.mp4 │ Elasticsearch分享V2.pdf │ Elasticsearch分享V4.pdf │ ES分享试验环境.docx │ ES操作.txt │ Redis分享-张亚V2.pdf │ 日志收集.txt │ 监控和分词.txt │ 防脑裂配置.txt │ ├─新版MySQL DBA综合实战班 第13天-mongo │ 01mongo介绍.mp4 │ 02mongo安装配置优化.mp4 │ 03mongo增删改查.mp4 │ 04授权认证和索引.mp4 │ 05mongo常用工具介绍.mp4 │ 06mongo副本集升级备份恢复.mp4 │ 07ELK模板收集mongo日志.mp4 │ mongodb.jpg │ Mongodb分享-贾海娇.pdf │ mongo数据库分享-张亚V1.pdf │ monogdb.conf │ ├─新版MySQL DBA综合实战班 第14天 │ │ 1_MHA手工切换和GTID支持.mp4 │ │ 2_MMM高可用架构.mp4 │ │ 3_MySQL备份概念.mp4 │ │ 4_Mysqldump备份原理.mp4 │ │ 5_Mysqldump基于表备份.mp4 │ │ 6_MySQL全量恢复和日志增量恢复.mp4 │ │ 7_xtrabackup全量和增量备份恢复.mp4 │ │ 作业及答案.docx │ │ │ └─MySQL DBA堂命令-mha和备份恢复 │ mysql-master_05-18_10-03-09.log │ mysql-master_05-18_14-02-01.log │ mysql-mycat_05-18_10-03-02.log │ mysql-slave1_05-18_10-03-14.log │ mysql-slave2_05-18_10-03-20.log │ ├─新版MySQL DBA综合实战班 第15天 │ │ 1_课后作业讲解.mp4 │ │ 2_MySQL索引原理介绍.mp4 │ │ 3_MySQL索引类型介绍.mp4 │ │ 4_MySQL索引底层结构和执行计划.mp4 │ │ 5_MySQL索引优化原则.mp4 │ │ 6_MySQL运维常见错误part1.mp4 │ │ 7_MySQL运维常见错误part2.mp4 │ │ ERROR1040_1917970.1.pdf │ │ ERROR1062_1593526.1.pdf │ │ ERROR1205_1911871.1.pdf │ │ ERROR2002_1023190.1.pdf │ │ How_to_Reset_the_RootPassword.pdf │ │ How_to_Reset_the_RootPassword5.7.pdf │ │ PacketTooLarge.pdf │ │ │ └─MySQL DBA课堂命令-索引调优和运维常见错误 │ mysql-master-05-25_11-10-39.log

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值