使用连接查询检索行

时间:2013-10-18 08:54:51

标签: postgresql

我有两张这样的表

A             B
----          -------       
col1  col2    col1   col2
----------    -----------

一个表包含300k行 B表包含400k行

我需要计算表A的col1,如果它匹配表B的col1 我写了这样一个查询:

select count(distinct ab.col1) from A ab join B bc on(ab.col1=bc.col1)

但这需要太多时间

2 个答案:

答案 0 :(得分:1)

可以尝试一组... 还要确保col1在两个表中都被索引

SELECT COUNT (col1 )
FROM
(
SELECT aa.col1
FROM A aa JOIN B bb on aa.col1 = bb.col1
GROUP BY (aa.col1)
)

答案 1 :(得分:1)

如果没有您提供更多详细信息,很难回答:您是否对表格进行了分析?你在每张桌子上都有col1的索引吗?你在计算多少行?

话虽如此,您的查询没有太多潜在的查询计划。您可能有两个seq扫描,这些扫描是连接在一起的,这是您可以做的最好的...如果您有大量的行数,那么您将计算数十亿行,这需要时间。

也许你可以用不同的方式重写查询?如果每个B.col1都在A.col1中,那么没有连接就可以获得相同的结果:

select count(distinct col1) from B

如果A的基数较低,则依赖exists()可能会更快:

with vals as (
  select distinct A.col1 as val from A
)
select count(*) from vals
where exists(select 1 from B where B.col1 = vals.val)

或者,如果您知道A.col1中的每个可能值并且它相当小,那么您可以在不查询A的情况下取消数组:

select count(*) from unnest(Array[val1, val2, ...]) as vals (val)
where exists(select 1 from B where B.col1 = vals.val)

反之亦然,在上述每一项中,如果每个B都保留参考值。