条件化简
移除不必要的括号
原条件:((a=5ANDb=c)OR((ac)AND(c5)))优化器会去掉括号:(a=5andb=c)OR(acANDc5)
常量传递(constant_propagation)
原条件:a=5ANDba优化器会变为常量:a=5ANDb5
移除没用的条件(trivial_condition_removal)
原条件:(a1andb=b)OR(a=6OR5!=5)可以被简化为:a1ORa=6
常量表检测
使用主键等值匹配或者唯一二级索引列等值匹配作为搜索条件来查询某个表,MySQL觉得这两种查询花费的时间特别少,少到可以忽略,原条件:SELECT*FROMtable1INNERJOINtable2ONtable1.column1=table2.column2WHEREtable1.primary_key=1;优化后:SELECTtable1表记录的各个字段的常量值,table2.*FROMtable1INNERJOINtable2ONtable1表column1列的常量值=table2.column2;
外连接消除
内连接的驱动表和被驱动表的位置可以相互转换,而左(外)连接和右(外)连接的驱动表和被驱动表是固定的。原sql:SELECT*FROMe1LEFTJOINe2ONe1.m1=e2.m2WHEREe2.n2ISNOTNULL;等价于:SELECT*FROMe1INNERJOINe2ONe1.m1=e2.m2WHEREe2.m2=2;
子查询优化
一些子查询的概念
标量子查询:只返回一个单一值的子查询行子查询:返回一条记录的子查询列子查询:查询出一个列的数据的子查询表子查询:包含很多条记录的子查询不相关子查询:查询可以单独运行出结果,而不依赖于外层查询的值相关子查询:子查询的执行需要依赖于外层查询的值
标量子查询、行子查询的执行方式
从外层查询中获取一条记录然后从上一步骤中获取的那条记录中找出子查询中涉及到的值
MySQL对IN子查询的优化
in的内容很少:直接内存中处理in的结果集很多:物化表(存储子查询结果集的临时表),他是一张临时表,临时表也会使用索引。物化表转连接:将in的语句变为连接查询将子查询转换为半连接(semi-join):只关心连接中是否有,不关心有几个!