Teradata替换自我加入

时间:2014-04-09 08:22:47

标签: sql teradata

我在Teradata有桌子并且拥有万亿的记录。  温度 - cat_nbr为PI

Cat_nbr | brand_Nbr |card_nbr
1       |  10       | 100
1       |   10      |101
1       |20         | 100
1       | 20        | 102
2       |10         | 100
2       | 10        |103
2       |30         |100
2       |30         |105
3       |40         |106
3       | 30        |107

我需要找出特定品牌的客户类别总数。 只是一个前。品牌号码:10 首先,我们需要检查哪只猫的品牌没有10,在这只猫1,2中有它。 然后对于猫1,2中的所有cutomer;我们需要计数(不同的card_no)。

结果应该像

brand_nbr|total_cust
10       | 5

我已经写了下面的查询来实现: -

select k.brand_nbr,count(distinct l.card_nbr) 
from temp k join temp l on k.cat_nbr=l.cat_nbr
group by 1;

它给了我正确的结果,但是事情,我们在表中有数万亿条记录,当我运行查询时,它继续处理超过2小时。

我需要一个解决方案来提高性能,以便最多可以在30分钟内完成。 我检查了放大器,我的数据库有16安培。

如果您有任何解决方案,请高手帮帮我。

提前致谢。

2 个答案:

答案 0 :(得分:0)

我能想到的另一种方法是使用两个步骤:

-- This will remove duplicates
CREATE VOLATILE SET TABLE vt AS
 (
   SELECT k.brand_nbr,l.card_nbr
   FROM temp k JOIN temp l ON k.cat_nbr=l.cat_nbr
  ) 
WITH DATA 
PRIMARY INDEX(brand_nbr)
ON COMMIT PRESERVE ROWS;

-- Now you can simply count without distinct
SELECT brand_nbr, COUNT(*)
FROM vtab
GROUP BY 1;

根据您的数据(每个cat_nbr / brand_nbr的行数),这可能会更快。或者更慢和完全倾斜: - )

顺便说一下,我怀疑你在16 AMP系统上存储了1万亿行,这至少是30TB,可能是16个节点

答案 1 :(得分:0)

如果您不想将volatile表创建为一个集合(如建议的dnoeth),请尝试使用有序的分析函数:

SELECT DISTINCT
k.brand_Nbr,
COUNT(l.card_nbr) OVER(PARTITION BY k.brand_Nbr) AS cnt
FROM temp k JOIN temp l ON k.cat_nbr=l.cat_nbr

有序分析函数不需要GROUP BY语句。我不确定它是否真的比关于性能的易失性表更好(因为dnoeth的解决方案中提到的易失性表也使用索引,理论上应该对Teradata更好),但是你可以尝试一下。