使用explain语法,对SQL进行解释,根据其结果进行调优:
MySQL 表关联的算法是 Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果:
a.EXPLAIN 结果中,第一行出现的表就是驱动表
b.
对驱动表可以直接排序,对非驱动表(的字段排序)需要对循环查询的合并结果(临时表)进行排序(Important!),即using temporary;
c. [驱动表] 的定义为:1)指定了联接条件时,满足查询条件的
记录行数少的表为[驱动表];2)未指定联接条件时,
行数少的表为[驱动表](Important!)。
d.
优化的目标是尽可能减少JOIN中Nested Loop的循环次数,以此保证:
永远用小结果集驱动大结果集(Important!)!:A JOIN B,A为驱动,A中每一行和B进行循环JOIN,看是否满足条件,所以当A为小结果集时,越快。
e.NestedLoopJoin实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果还有第三个参与Join,
则再通过前两个表的Join结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此往复
两表JOIN优化
a.当无order by条件时,根据实际情况,使用left/right/inner join即可,根据explain优化 ;
b.当有order by条件时,如select * from a inner join b where 1=1 and other condition order by a.col;使用explain解释语句;
1)如果第一行的驱动表为a,则效率会非常高,无需优化;
2)否则,因为只能对驱动表字段直接排序的缘故,会出现using temporary,所以此时需要使用
STRAIGHT_JOIN明确a为驱动表,来达到使用a.col上index的优化目的;
或者使用left join且Where条件中不含b的过滤条件,此时的结果集为a的全集,
而STRAIGHT_JOIN为inner join且使用a作为驱动表