2017-07-27 28 views
0

我在AWS redshift中有2个表。具体内容如下在Redshift中使用连接的最佳方式

一)印象(计算特定广告的曝光次数)

  1. 行(170万美元)
  2. 分发密钥(ad_campaign)
  3. 排序键数的数(created_on)

b)点击次数(计算特定广告的点击次数)。

  1. 行(80亿美元)
  2. 分发密钥(ad_campaign)
  3. 排序关键字(created_on)

数我有2片单DC1大型集群。

我试图运行下面的查询

select impressions.offer_id, count(imp_cnt) from 
    bidsflyer.tblImpressionLog_Opt impressions 
full join bidsflyer.tblTrackingLinkLog_Opt clicks 
    on impressions.offer_id=clicks.offer_id and date_trunc('week', 
impressions.created_on)=date_trunc('week', clicks.created_on) 
    where impressions.created_on >= '2017-07-27 00:00:00' 
    group by 1 

这个查询需要更多的则8分钟运行。考虑到数据量,我认为这是相当大的,我认为这不是很大。

查询计划看起来像下面

XN HashAggregate (cost=2778257688268.43..2778257688268.60 rows=67 width=12) 
     -> XN Hash Left Join DS_DIST_NONE (cost=179619.84..2778170875920.65 rows=17362469555 width=12) 

    Hash Cond: (("outer".offer_id = "inner".offer_id) AND (date_trunc('week'::text, "outer".created_on) = date_trunc('week'::text, "inner".created_on))) 

    -> XN Seq Scan on tblimpressionlog_opt impressions (cost=0.00..724967.36 rows=57997389 width=20) 
      Filter: (created_on >= '2017-07-27 00:00:00'::timestamp without time zone) 

    -> XN Hash (cost=119746.56..119746.56 rows=11974656 width=12) 
      -> XN Seq Scan on tbltrackinglinklog_opt clicks (cost=0.00..119746.56 rows=11974656 width=12) 

东西谁能给我分配的密钥的正确用法的指导和排序键。

我应该如何设计我的查询?

+0

如果速度是重中之重,我强烈建议您至少使用2个节点。 –

回答

1

表设置:

1)按照计划,最贵的操作由offer_id分组。这很有意义,因为您没有按照offer_id对数据进行排序或分发。您的表格非常大,所以您可以使用交叉排序键(offer_id,created_on)(交错键应该给包含的列赋予相等且与顺序无关的权重,并且已知对较大的表具有积极影响)来重新创建表。 2)如果你加入数星期,你可以实现你的星期列(创建一个物理列,并用date_trunc输出填充它)。这可能会节省一些计算工作量,以便在加入期间动态获取这些值。但是,此操作很便宜,如果您的表已按时间戳列进行排序,则Redshift可能已经只扫描了适当的块。此外,如果每个要约都运行一段时间(即要约列具有较高的基数和与时间列的高度相关性),则可以使用复合排序键(offer_id,week_created),这将允许更快的合并连接和聚合也会很快乐。

3)如果在其他查询中不使用ad_campaign,则可以通过offer_id分配两个表。加入发布密钥列是一种好的做法,因为您拥有单个节点并且分发风格主要影响多节点设置,所以您的查询不太可能从中受益。所有建议只是假设,不知道数据的确切性质,它们需要运行基准测试(使用建议的配置创建表,复制数据,真空,分析,运行相同的查询至少3次,并将时间与原始设置)。如果你这样做,并在这里发布结果,我将不胜感激。

RE查询本身,你可以用JOIN取代FULL JOIN,因为你不需要它。当你想要得到的不仅仅是没有相关的点击和反之亦然两个表,也展示路口FULL JOIN应该被使用。这似乎情况并不因为你是impressions.created_on和组过滤通过impressions.offer_id。所以,你需要的只是交叉路口。通过简单的更换JOINFULL JOIN可能会影响查询性能。如果你想看到零点击的优惠,你可以使用LEFT JOIN

1

合并连接快于散列连接,你应该努力实现合并连接。你按键看起来没问题,但是你的数据实际上是排序的吗?红移不会自动保存搜索结果排序方式排序的关键表中的行,就没有办法为红移来执行你的桌子上合并连接。在桌面上运行一个完整的真空,红移将开始执行合并连接。

select * from svv_table_info where table = 'impressions' 
select * from svv_table_info where table = 'clicks' 

使用上面的查询来检查您在表中的未排序数据量。
在你的桌子上运行一个完整的真空。根据未排序数据的数量,这可能需要一段时间并使用大量群集资源。

VACUUM impressions to 100 percent 
VACUUM clicks to 100 percent 

如果我做了一个错误的假设,请评论,我会重新调整我的答案。

+0

感谢拉胡尔的回答。将尝试这些建议 –