我想从多个表中检索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
可以减轻一些表扫描。
答案 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)
根据上面的评论,我会建议以下内容 - 我认为,由于为服务器提供了最优化流程的机会,因此最有可能提供良好的性能。我没有做过任何测试,也没有任何东西支持这种期待经验和直觉:
使用ID类型的单个列创建临时表。为此列添加索引。
对于第一个表,选择所有id并插入此表。
对于以下每个表,选择除临时表(例如不在其中)之外的所有ID,并插入临时表。
使用临时表执行实际查询。
你的第二个查询不一样。我相信这就是你的意思
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。看起来更丑陋,我需要进行测试,看看它是否更慢,我希望一个好的优化器能够在两者上都有相同的性能。