联合加入公共表

时间:2009-08-18 20:40:07

标签: sql database

我有一个目前看起来像这样的查询(我会简化它以达到目的):

select shipment.f1, type1detail.f2
from shipment
join type1detail using (shipmentid)
where shipment.otherinfo='foo'
union
select shipment.f1, type2detail.f2
from shipment
join type2detail using (shipmentid)
where shipment.otherinfo='foo'

也就是说,我们有两种类型的详细信息可以在货件上,我需要查找满足给定条件的所有货件的两种类型的所有记录。 (想象一下,两个细节表有一些匹配数据的字段。在现实生活中,还有几个连接;正如我所说,我正在尝试简化查询以解决我今天要问的问题。)

但是“where”子句需要全文件扫描,因此完成两次完整文件扫描效率非常低。从逻辑上讲,数据库引擎应该能够找到满足条件一次的货运记录,然后找到type1detail和type2detail中的所有记录,其中shipmentid与这些值匹配。

但我怎么在SQL中这样说呢?

select shipment.f1, detail.f2
from shipment
join
(select shipmentid, f2
from type1detail
union
selection shipmdentid, f2
from type2detail
) d using (shipmentid)
where shipment.otherinfo='foo'

需要对type1detail进行完整文件扫描,并使用type2detail的完整文件扫描进行联合,然后将其加入到装运中,这比读取装运两次更糟糕。 (因为每个细节表都大于装运。)

这似乎是一件想要做的直截了当的事情,但我想不出能表达出来的方式。

如果你知道特定于该引擎的解决方案,我正在使用Postgres,但我希望有一个通用的SQL解决方案。

2 个答案:

答案 0 :(得分:1)

我会使用临时表将shipmentid转储到匹配你的“otherinfo”where子句。然后在连接中使用该临时表(不替换任何现有连接,但添加另一个连接),以便连接条件仅使用shipmentids并且不需要where子句(除非您还要过滤不在出货表中的列,但是关键是你仍然只扫描过那张桌子一次。)

答案 1 :(得分:0)

如果你偶尔运行这个查询,你可能最好不要索引otherinfo列以完全避免完整的扫描。我对Postgres的工作量不大,但看起来至少有一个full text indexing option already.