在Redshift中使用连接的最佳方式

时间:2017-07-27 13:27:22

标签: amazon-redshift

我在AWS redshift中有2个表。详情如下

a)展示次数(计算特定广告的展示次数)

  1. 行数(1.7亿)
  2. 分配密钥(ad_campaign)
  3. 排序键(created_on)
  4. b)点击次数(计算特定广告的点击次数)。

    1. 行数(8000万)
    2. 分配密钥(ad_campaign)
    3. 排序键(created_on)
    4. 我有一个包含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)
      

      任何人都可以向我提供正确使用分发密钥和排序密钥的指导。

      我该如何设计查询?

2 个答案:

答案 0 :(得分:1)

表格设置:

1)根据计划,最昂贵的操作是通过offer_id进行分组。这是有道理的,因为您没有按offer_id对数据进行排序或分发。您的表非常大,因此您可以使用(offer_id,created_on)的交错排序键重新创建表(交错键应该为包含的列提供相等且与顺序无关的权重,并且已知对较大的表有积极影响)。

2)如果您按周加入,则可以实现您的周列(创建一个物理列并使用date_trunc输出填充它)。这可能会节省一些计算工作量,以便在连接期间动态获取这些值。但是,此操作很便宜,如果您的表已经按时间戳列排序,则Redshift可能已经只扫描了相应的块。此外,如果每个要约运行一小段时间(意味着要约栏具有高基数和与时间列的高度相关性),您可以通过(offer_idweek_created)获得复合排序键合并加入速度更快,聚合也很快乐。

3)如果您未在其他查询中使用ad_campaign,则可以按offer_id分发这两个表格。在分发密钥中加入列是一种很好的做法,因为您有一个节点并且分发方式主要影响多节点设置,所以您的查询不太可能从中受益。

所有建议都只是假设,而不知道数据的确切性质,它们需要运行基准测试(创建具有推荐配置的表,复制数据,真空,分析,运行相同的查询至少3次,并将时间与原始设置)。如果您这样做并在此处发布结果,我将不胜感激。

重新启用查询本身,您可以将FULL JOIN替换为JOIN因为您不需要它。如果您不仅希望获得两个表格的交集,还希望获得不具有相关点击次数的展示次数,则应使用FULL JOIN,反之亦然。这似乎并非如此,因为您按impressions.created_on过滤并按impressions.offer_id分组。所以,你所需要的只是交集。用简单的FULL JOIN替换JOIN也可能会影响查询性能。如果您想查看零点击的优惠,可以使用LEFT JOIN

答案 1 :(得分:1)

合并连接比散列连接更快,您应该尝试实现合并连接。您排序键看起来没问题,但您的数据是否实际排序? Redshift不会自动保持表的行按排序键排序,redshift无法在表上执行合并连接。在桌面上运行完全真空,redshift将开始执行合并连接。

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

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

相关问题