PostgreSQL:选择不同的id union和select id full join

时间:2015-10-08 16:16:26

标签: sql postgresql

我想从多个表中检索id的完整列表,它们可以完全重叠或互斥。我想知道哪个会有更好的性能,哪个是PostgreSQL的正确方法,为什么会这样呢?

假设我有4个表,并且使用索引优化表:

[SELECT DISTINCT ... UNION]

SELECT DISTINCT id from table1
UNION
SELECT DISTINCT id from table2
UNION
SELECT DISTINCT id from table3
UNION
SELECT DISTINCT id from table4
;

[选择...完全加入]

SELECT DISTINCT coalesce(a.id, b.id, c.id, d.id) AS id
FROM table1 a
FULL JOIN table2 b on a.id=b.id
FULL JOIN table3 c on b.id=c.id
FULL JOIN table4 d on c.id=d.id
;

在这里做了一些调整。感谢@ Hogan在回答中提出的建议。

备注

我对full join的全部动机是因为id字段可能在表之间完全重叠。 full join可以减轻一些表扫描。

2 个答案:

答案 0 :(得分:0)

这两者并不相同。第一个做你想要的;第二个没有。从这个角度来看,"表现"奖励归于第一:正确的结果超越了更快的查询。

这修复了第二个版本:

SELECT id
from table1 a FULL JOIN
     table2 b
     using (id) FULL JOIN
     table3 c
     using (id) FULL JOIN
     table4
     using (id);

(如果其中一个表可能有多个ID,则只需要distinct。)

与任何性能问题一样,您应该尝试使用系统中的数据。

答案 1 :(得分:0)

根据上面的评论,我会建议以下内容 - 我认为,由于为服务器提供了最优化流程的机会,因此最有可能提供良好的性能。我没有做过任何测试,也没有任何东西支持这种期待经验和直觉:

  1. 使用ID类型的单个列创建临时表。为此列添加索引。

  2. 对于第一个表,选择所有id并插入此表。

  3. 对于以下每个表,选择除临时表(例如不在其中)之外的所有ID,并插入临时表。

  4. 使用临时表执行实际查询。

  5. 你的第二个查询不一样。我相信这就是你的意思

    SELECT DISTINCT coalesce(a.id,b.id,c.id,d.id) as id
    from table1 a
    FULL JOIN table2 b on a.id=b.id
    FULL JOIN table3 c on b.id=c.id
    FULL JOIN table4 d on c.id=d.id
    
    这种方式def。看起来更丑陋,我需要进行测试,看看它是否更慢,我希望一个好的优化器能够在两者上都有相同的性能。