2017-07-27 18 views
0

AWS redshiftに2つのテーブルがあります。詳細はRedshiftでの結合を使用する最適な方法

下記a)の感想(特定の広告のインプレッション数をカウントする)

  1. は、行の数(1.7億)
  2. 分散キー(ad_campaign)
  3. ソートキーとしてあります(created_on)

b)クリック(特定の広告のクリック数をカウントする)。行(8000万)

  • 分散キー(ad_campaign)
  • ソートキー(CREATED_ON)
    1. 番号iは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でソートしたり配布したりしなかったので意味があります。あなたのテーブルはかなり大きいので、インターリーブされたソートキーを使ってテーブルを再作成することができます(インターリーブされたキーは、含まれているカラムに等しく、オーダーに依存しないウェイトを与えられ、大きなテーブルにプラスの効果をもたらすことが知られています)。

    2)週に参加する場合は、週の列を実体化することができます(物理的な列を作成し、date_truncの出力を入力します)。これにより、結合中にこれらの値を動的に取得するための計算量を節約できます。ただし、この操作は安価です。テーブルがすでにタイムスタンプ列でソートされている場合、Redshiftは適切なブロックのみをスキャンしている可能性があります。また、各オファーが短期間実行される場合(オファー列のカーディナリティが高く、時間列との相関が高いことを意味します)、より速いマージ結合を可能にする複合ソートキー(offer_idweek_created)速くも楽しいでしょう。

    3)他のクエリでad_campaignを使用しない場合は、両方のテーブルをoffer_idで配信できます。ディストリビューションキーに列を結合することは良い方法です。単一のノードがあり、ディストリビューションスタイルがマルチノード設定に大部分影響を与えるため、クエリの利点はほとんどありません。

    すべての推奨事項は、データの正確な性質を知らないだけの仮定です。ベンチマークを実行する必要があります(推奨構成のテーブルを作成する、データをコピーする、vacuumuuを分析する、同じクエリを少なくとも3回実行する、元の設定)。あなたがこれを行い、ここに結果を投稿すれば、私は感謝します。

    クエリ自体では、FULL JOINJOINに置き換えることはできません。 FULL JOINは、両方のテーブルの交差点だけでなく、関連するクリックがないインプレッションやその逆を取得する場合に使用します。 impressions.created_onでフィルタリングし、グループをimpressions.offer_idで除外しているため、このようには見えません。だから、あなたが必要とするのは、交差点だけです。 FULL JOINを単純な0​​に置き換えることも、クエリのパフォーマンスに影響する可能性があります。クリック数がゼロのオファーを表示する場合は、LEFT JOINを使用できます。

    1

    マージ結合はハッシュ結合より高速ですが、マージ結合を実行してください。ソートキーは大丈夫ですが、データは実際にソートされていますか? 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 
    

    私が間違った仮定をしてしまった場合は、私の答えに焦点を合わせます。

    +0

    あなたの答えはRahulに感謝します。これらの提案を試してみる –

    関連する問題