为什么STRAIGHT_JOIN如此彻底地改善了这个查询,当它被写入SELECT关键字之后又是什么意思呢?

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

STRAIGHT_JOIN和JOIN类似,只是左边的表总是在右边的表之前被读取。 这可以用于连接优化器以错误的顺序放置表的那些(less数)情况。

什么? 我可以写:

 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 

而且花费的时间不到一秒钟,这种语法看起来甚至不合法。

我想第二个例子意味着一个STRAIGHT_JOIN将被用于每当一个INNER JOIN被写入,但是我不能find任何关于它的文档。

这里发生了什么事情,“连接优化器”如何导致这种相对较差的性能呢? 我应该总是使用STRAIGHT_JOIN吗? 我怎么知道什么时候使用它?

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

谢谢

这里发生了什么事情,“连接优化器”如何导致这种相对较差的性能呢?

STRAIGHT_JOIN强制表的连接顺序,所以在外循环中扫描table1 ,在内循环中扫描table2

优化器并不完美(尽pipe还挺好的),最可能的原因是过时的统计。

我应该总是使用STRAIGHT_JOIN

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

我怎么知道什么时候使用它?

你应该收集统计数字,build立双方的计划,并理解这些计划是什么意思。

如果你看到:

  1. 自动生成的scheme不是最优的,不能用标准的方法来改进,

  2. STRAIGHT_JOIN版本更好,你明白它总是会明白为什么它总是会

,然后使用STRAIGHT_JOIN