【发布时间】:2017-06-03 08:15:03
【问题描述】:
我在 mysql 中有一个大型查询,涉及将多个表连接在一起。它太慢了,所以我做了“解释”,发现它正在创建一个临时表,我怀疑它占用了大部分执行时间。我找到了一些相关信息:
- The mysql docs 描述创建临时表时的条件可能。 (“服务器在这样的条件下创建临时表...”[强调])
- 这个相关的 SO 问题 Using index, using temporary, using filesort - how to fix this?,它提供了该文档的链接并将其应用于特定案例。
- 这个相关的 SO 问题 Order of join conditions important? 讨论了连接的评估顺序。
我的查询似乎不满足文档 #1 中列出的任何条件,按照我编写连接的顺序。 但是,通过实验,我发现如果我删除我的order by 子句,没有创建临时表。这让我从文档中看到了这条规则:
评估包含 ORDER BY 子句和不同 GROUP BY 子句的语句,或者 ORDER BY 或 GROUP BY 包含来自连接队列中第一个表以外的表的列。
这与上面 #2 的示例中使用的规则相同,但在 #2 中,OP 在 order by 子句中明确包含来自多个表的列,因此至少在表面上有所不同。
此外,当我查看explain 的输出时,我首先列出的表似乎没有被优化器首先使用。放下一个伪查询例如:
select * from A
join B on A.c1=B.c1
join C on A.c2=C.c2
where A.c3='value'
order by A.c4
我会说我的order by 子句确实只使用“连接队列中的第一个表”中的列根据我编写查询的顺序。另一方面, explain 的输出表明它首先考虑表 B,然后是表 A。
以下是问题:
- 上面引用的临时表使用规则是指我编写表的顺序还是软件选择评估它们的顺序?
- 如果是我编写它们的顺序,这是否意味着连接的顺序会影响性能? (似乎与上述#3 的主张相矛盾。)
- 如果是软件选择评估它们的顺序,有没有办法强制或欺骗它选择不使用表格的顺序?
【问题讨论】:
标签: mysql join optimization explain