我有以下MySql查询:
select t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID
where t1.FilterID = 1
Run Code Online (Sandbox Code Playgroud)
运行大约需要30秒,这很奇怪,因为如果我注释掉连接或where子句,它需要不到一秒钟:即
select t1.*
from Table1 t1
where t1.FilterID = 1
Run Code Online (Sandbox Code Playgroud)
要么
select t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID
Run Code Online (Sandbox Code Playgroud)
每个不到一秒钟.
然后是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
Run Code Online (Sandbox Code Playgroud)
并且查询在不到一秒的时间内执行.
更奇怪的是,我可以写:
select STRAIGHT_JOIN t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID
where t1.FilterID = 1
Run Code Online (Sandbox Code Playgroud)
它只需不到一秒钟,这种语法似乎不合法.
我猜第二个例子意味着只要写入INNER JOIN就会使用STRAIGHT_JOIN,但我找不到任何关于它的文档.
这里发生了什么,以及"加入优化器"如何导致这种相对较差的性能?我应该一直使用STRAIGHT_JOIN吗?我怎么知道何时使用它?
Table1和Table2都有整数主键; FilterID是另一个表的外键; CommonID列是第三个表的外键.他们都有索引.数据库引擎是InnoDB.
谢谢
Qua*_*noi 43
这里发生了什么,以及"加入优化器"如何导致这种相对较差的性能?
STRAIGHT_JOIN
强制表的连接顺序,因此table1
在外循环和table2
内循环中扫描.
优化器并不完美(虽然相当不错),最可能的原因是过时的统计数据.
我应该经常使用吗?
STRAIGHT_JOIN
不,只有当优化器出错时.这可能是您的数据分布严重偏差或无法正确计算(例如,对于空间或全文索引).
我怎么知道何时使用它?
您应该收集统计数据,为两种方式构建计划并了解这些计划的含义.
如果你看到:
自动生成的计划不是最优的,无法通过标准方式进行改进,
该STRAIGHT_JOIN
版本更好,你了解它总是会和理解,为什么它总是会
,然后使用STRAIGHT_JOIN
.
归档时间: |
|
查看次数: |
21856 次 |
最近记录: |