为什么STRAIGHT_JOIN如此大幅度地改进了这个查询,以及在SELECT关键字之后编写它意味着什么?

时间:2011-04-28 12:47:37

标签: mysql join

我有以下MySql查询:

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

运行大约需要30秒,这很奇怪,因为如果我注释掉join或where子句,则需要不到一秒的时间: 即。

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关键字,我可以在这里找到一个参考: http://dev.mysql.com/doc/refman/5.0/en/join.html

  

STRAIGHT_JOIN类似于JOIN,   除了左表总是   在右表之前阅读。这个可以   用于那些(少数)案件   连接优化器放置的   表格顺序错误。

什么? 我可以写:

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

并且查询在不到一秒的时间内执行。

更奇怪的是,我可以写:

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

并且只需不到一秒钟,这种语法似乎不合法。

我猜第二个例子意味着只要写入INNER JOIN就会使用STRAIGHT_JOIN,但我找不到任何关于它的文档。

这里发生了什么,以及“加入优化器”如何导致这种相对较差的性能?我应该一直使用STRAIGHT_JOIN吗?我怎么知道何时使用它?

Table1和Table2都有整数主键; FilterID是另一个表的外键; CommonID​​列是第三个表的外键。他们都有索引。数据库引擎是InnoDB。

由于

1 个答案:

答案 0 :(得分:40)

  

这里发生了什么,以及“加入优化器”如何导致这种相对较差的性能?

STRAIGHT_JOIN强制执行表的连接顺序,因此在外循环中扫描table1,在内循环中扫描table2

优化器并不完美(虽然相当不错),最可能的原因是过时的统计数据。

  

我应该始终使用STRAIGHT_JOIN

不,只有当优化器出错时。这可能是您的数据分布严重偏差或无法正确计算(例如,对于空间或全文索引)。

  

我怎么知道何时使用它?

您应该收集统计数据,为这两种方式制定计划,并了解这些计划的含义。

如果你看到:

  1. 自动生成的计划不是最优的,无法通过标准方式进行改进,

  2. STRAIGHT_JOIN版本更好,您了解它始终会理解为什么总是会

  3. ,然后使用STRAIGHT_JOIN