【性能提高神器】STRAIGHT_JOIN

今天给你们下另外一个性能提高神器-STRAIGHT_JOIN,在数据量大的联表查询中灵活运用的话,能大大缩短查询时间。html

首先来解释下STRAIGHT_JOIN究竟是用作什么的:mysql

STRAIGHT_JOIN is similar to JOIN, except that the left table is always read before the right table. 
This can be used for those (few) cases for which the join optimizer puts the tables in the wrong order.

意思就是说STRAIGHT_JOIN功能同join相似,但能让左边的表来驱动右边的表,能改表优化器对于联表查询的执行顺序。sql

接下来咱们举个例子进行大体的分析:mysql优化

 

select t1.*
from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1

 

以上sql大数据量下执行须要30s,是否是很奇怪?明明Table1表的FilterID字段建了索引啊,Table1和Table2的CommonID也建了索引啊。经过explain来分析,你会发现执行计划中表的执行顺序是Table2->Table1。这个时候要略微介绍下驱动表的概念,mysql中指定了链接条件时,知足查询条件的记录行数少的表为驱动表;如未指定查询条件,则扫描行数少的为驱动表。mysql优化器就是这么粗暴以小表驱动大表的方式来决定执行顺序的性能

但以下sql的执行时间都少于1s:大数据

select t1.*
from Table1 t1 where t1.FilterID = 1

优化

select t1.*
from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID

 这个时候STRAIGHT_JOIN就派上用场,咱们对sql进行改造以下:this

select t1.*
from Table1 t1 STRAIGHT_JOIN Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1

用explain进行分析,发现执行顺序为Table1->Table2,这时就由Table1来做为驱动表了,Table1中相应的索引也就用上了,执行时间居然低于1s了。spa

分析到这里,必需要重点说下:code

  • STRAIGHT_JOIN只适用于inner join,并不使用与left join,right join。(由于left join,right join已经表明指定了表的执行顺序)
  • 尽量让优化器去判断,由于大部分状况下mysql优化器是比人要聪明的。使用STRAIGHT_JOIN必定要慎重,由于啊部分状况下认为指定的执行顺序并不必定会比优化引擎要靠谱。

 

扩展阅读:

https://stackoverflow.com/questions/512294/when-to-use-straight-join-with-mysql

https://stackoverflow.com/questions/5818837/why-does-straight-join-so-drastically-improve-this-query-and-what-does-it-mean

https://dev.mysql.com/doc/refman/8.0/en/join.html

相关文章
相关标签/搜索