USING
查询的ON
子句中的FROM
构造(而不是SELECT
)可能会引入优化障碍。我的意思是这个关键词: />
SELECT * FROM a JOIN b USING (a_id)
只是在更复杂的情况下。
上下文:对此问题的评论。到目前为止的任何事情。我对一个展示效果或进一步信息的链接的测试案例非常感兴趣。我的搜索工作空了。 />
#1 楼
欧文:我同意这样的想法,即使用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个小时才能运行。通过分布左连接,可以将键按下,查询只需几秒钟即可完成。当然,这并不完全等效,这就是为什么计划人员无法将它们视为等效对象,因此它只能将该计划视为哈希联接,然后进行嵌套循环,这非常缓慢。
每当您强行以某种顺序严格执行连接时,都会引入一些情况,即在计划的执行过程中可能尚无法使用关键过滤器信息,因此以后可以在快速索引中执行哪些操作在嵌套循环/顺序扫描中,扫描/哈希联接的执行速度可能要慢得多,因此,尽管上面的片段并非立即等效,但它显示了相同的问题。
评论
@kgrittn:到目前为止,这是我通常所期望的:使用速度稍快-因为它导致结果矩阵中的列减少一列。您的发现可以追溯到2005年和2008年。我认为到目前为止,所有问题都已得到解决。但是,我看到一个可能的限制:可能必须按顺序应用具有USING的JOIN,因为生成的连接列是一个联合产品。因此可能限制了JOIN的重新排序选项。我发现此线程可能与使我不再使用该线程有关,因为在联接上使用USING条件的VIEW可能导致转储/恢复出现问题:archives.postgresql.org/pgsql- bugs / 2011-06 / msg00030.php我仍然有na的感觉,还有另一个与使用性能问题相关的线程,其中解决方法是使用ON,但是我想放弃寻找它。在视图之外使用它可能是安全的,并且如果查询很慢,请记住要尝试使用ON作为诊断步骤。
看起来像“使用”使代码更具可读性,但是我想两个字段都需要相同的名称。我不认为使用会比“开”更好的性能,因为数据库无论如何都需要进行匹配,就像选择具有与联接一样的性能(如果我错了,请纠正我),区别在于Join更干净,更易于维护。
@HLGEM:这只是一个符号名称,只有两个表,就像在我的示例中一样,没有混淆的空间。不过,我修改了这个问题。不想鼓励不幸地使用id作为列名。
@ChristiaanWesterbeek:我不同意。深入了解Postgres的“必去之处”是(仍然)邮寄。只有极少数的Postgres开发人员活跃在SO上,但是所有Postgres开发人员和专家都阅读了邮件列表