在某些情况下,在JOIN子句中使用构造可以引入优化障碍吗?


35

引起我注意的是查询子句中USING构造(而不是ON)在某些情况下可能会引入优化障碍。FROMSELECT

我的意思是这个关键词:

选择 *
从一个
加入b 使用(a_id)

仅在更复杂的情况下。

背景:此评论这个问题

我用这个了很多,从来没有发现过这么远。我对一个展示效果或进一步信息的链接测试案例非常感兴趣。我的搜索工作空虚。

USING (a_id)与替代连接子句相比,完美的答案是显示性能较差的测试用例ON a.a_id = b.a_id- 如果这确实可能发生。


2
@kgrittn:到目前为止,这是我通常所期望的:速度USING -因为结果矩阵中的列减少了一列。您的发现可以追溯到2005年和2008年。我认为到目前为止,所有问题都已得到解决。但是,我看到一个可能的局限性:USING可能必须按顺序应用的 JOIN ,因为生成的连接列是一个联合产品。从而潜在地限制了JOIN的重新排序中的选项。
Erwin Brandstetter 2012年

1
我发现此线程可能与使我不再使用该线程有关,因为在联接上使用USING条件的VIEW可能导致转储/恢复出现问题:archives.postgresql.org/pgsql- bugs / 2011-06 / msg00030.php 我仍然有na的感觉,还有另一个与使用性能问题相关的线程,其中解决方法是使用ON,但是我想放弃寻找它。在视图之外使用它可能是安全的,并且如果查询很慢,请记住要尝试将其作为诊断步骤进行尝试。
kgrittn 2012年

1
看起来像“使用”使代码更具可读性,但是我想两个字段都需要相同的名称。我不认为使用会比“开”更好的性能,因为数据库无论如何都需要进行匹配,就像选择具有与联接一样的性能(如果我错了,请纠正我),区别在于Join更加干净并且易于维护。
jcho360

2
@HLGEM:这只是一个符号名称,只有两个表,就像在我的示例中一样,没有混淆的空间。不过,我修改了这个问题。不想鼓励不幸使用idas作为列名。
Erwin Brandstetter,2012年

2
@ChristiaanWesterbeek:我不同意。深入了解Postgres答案的“前往” (仍然)邮寄。只有极少数Postgres开发人员活跃于SO上,但是所有Postgres开发人员和专家都阅读了邮件列表
a_horse_with_no_name

Answers:


12

欧文:我同意这样的想法,即使用USU导致严格的排序可能会在很多边缘情况下排除最佳计划。我最近帮助了在查询中遇到类似问题的人:

LEFT JOIN ( 
     a 
     JOIN b ON a.id = b.a_id
     JOIN c ON b.c_id = c.id
) ON a.id = something.a_id
LEFT JOIN (
     table1 t1
     JOIN table2 t2 ON t1.some_field = t2.other_field
     JOIN talbe3 t3 ON t2.yafield = t3.something_else
) ON ....
repeat a few more times

在他的情况下,这些连接块中最糟糕的是导致大约200k行(约2万次)的嵌套循环连接(进行数学运算),并且由于无法将键推入索引,因此这是顺序扫描。这意味着由于级联计划的更改,整个查询需要大约3个小时才能运行。通过分布左连接,可以将键按下,查询只需几秒钟即可完成。当然,这并不是完全等效的,这就是为什么计划人员无法将它们视为等效的原因,所以它只能将计划视为哈希联接,然后进行嵌套循环,这很慢。

每当您严格按一定顺序强制执行连接时,都会出现一些情况,即在执行计划时可能尚不提供关键过滤器信息,因此以后在快速索引扫描/哈希连接中可能会做些什么在嵌套循环/顺序扫描中可能必须做得慢得多,因此尽管上面的片段并不是立即等效的,但它显示了相同的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.