条件简化
1.移除不必要的括号
2.常量传递
3.等值传递
4.表达式计算
5.HAVING子句和WHERE子句的合并
子查询的执行方式
- 对于包含不相关的标量子查询或者行子查询的语句来说,MySQL会分别独立执行外层查询和子查询,就当作两个单表查询就行
- 对于相关的标量子查询或者行子查询,它的执行方式如下:
IN子查询优化
如果子查询的结果集中的记录条数很少,那么把子查询和外层查询分别看成两个单独的单表查询效率还是很高的,但是子查询的结果集太多的话会导致一下问题
- 结果集太多,内存无法存下
- 对于外层查询来说,如果子查询的结果集太多,就意味着IN子句中的参数很多,会导致(1.无法有效的使用索引,只能对外层查询进行全表扫描 2.在对外层查询执行全表扫描时,由于IN子句中的参数太多,这会导致检测一条记录是否符合和IN子句中的参数匹配花费的时间太长)
解决办法:不直接将不相关子查询的结果集当作外层查询的参数,而是将该结果写入一个临时表(1.该临时表的列就是子查询结果集中的列 2.写入临时表的记录会被去重 3.一般情况下子查询结果不会大的离谱,所以会为集合中的数据建立基于内存的存储引擎的临时表,并为该表建立哈希索引,如果子查询结果很大,会转而使用基于磁盘的存储引擎来保存结果集中的记录,索引类型也对应转变为B+树索引)
物化表转连接
松散索引扫描
如果IN子查询不满足转换为semi-join的条件,又不能转换为物化表或者转换为物化表的成本太大,那么它就会转换为EXISTS查询