dbt

dbt Redshift アダプター: DISTKEY / SORTKEY を使いこなす実務と試験対策

2026-04-19
NicheeLab編集部

Redshift は分散並列処理を前提にしたデータウェアハウスで、テーブルの分散(DISTSTYLE/DISTKEY)とソート(SORTKEY)が実行計画と I/O に直接影響します。dbt-redshift はこれらをモデル設定として宣言できるため、スキーマに埋め込むように最適化を管理できます。

近年は Redshift の自動最適化機能が進んだ一方、スター・スキーマのようにパターンが明確なワークロードでは、手動での DISTKEY / SORTKEY 設計が今も効果的です。この記事では、設計指針、dbt での記述、変更時の運用、試験で問われやすい要点をコンパクトにまとめます。

Redshift の分散・ソートと dbt モデルの関係

Redshift はデータをノード群に分散格納し、テーブルの分散方式(DISTSTYLE)と分散キー(DISTKEY)で行の配置を決めます。さらに SORTKEY が物理的な並び順を制御し、範囲フィルタやマージ結合の I/O を抑えます。これらは結合のデータ移動(redistribute/broadcast)の有無、スキャン量、同時実行時のスロット消費に直結します。

dbt-redshift ではモデル設定として diststyle、dist、sort、sort_type を宣言できます。コードとして構成化できるため、ブランチや環境ごとに安全に切り替えられ、リグレッションも検知しやすくなります。実務では、ワークロードの主な結合キーとアクセスパターンを先に固め、それに合わせて dbt のモデル設定を決めるのが手戻りの少ない進め方です。

  • まずは主要な結合を洗い出し、事実テーブルの DISTKEY 候補を特定する
  • 範囲条件で最も使う日時列などを先頭に据えた SORTKEY(COMPOUND)を検討する
  • 小さなディメンションは DISTSTYLE ALL を選ぶと大規模ファクトとの結合が安定しやすい
  • ワークロードが読めない初期段階は DISTSTYLE AUTO から始め、メトリクスを見て明示指定に切り替える

DISTSTYLE/DISTKEY の選び方とデータ配置のイメージ

分散方式は主に AUTO、KEY、ALL、EVEN があります。KEY は指定列のハッシュで行をノードに割り当て、同じキーの行を同一ノードに集めます。ALL は小さなテーブルを全ノードに複製し、大きな事実テーブルとの結合でデータ移動を避けます。EVEN はキーに依存せず均等分散します。AUTO はクラスタが適切と判断する方式を選ぶモードで、初期構築や不確実なワークロードに向きます。

KEY を選ぶ場合は、高カーディナリティで偏りが小さく、結合で頻用される列を選ぶのが原則です。偏りの大きいキーや時系列の単調増加列は、ノード間のデータ不均衡やホットスポットを招きがちです。

  • KEY: 主結合キーが明確で、データ分布の偏りが小さいとき
  • ALL: 小さいディメンションを大きなファクトに結合するとき
  • EVEN: 明確な結合キーがなく広く参照される中規模テーブル
  • AUTO: 初期段階や混在ワークロード。後から明示指定に切り替えやすいようにモデルを分離しておく

DISTKEY によるハッシュ分散の概念図

hash(distkey)hash(distkey)hash(distkey)Fact rows(distkey col)Node 1Slices ...Node 2Slices ...Node 3Slices ...同じ distkey 値は同じノードに配置され、結合時のデータ移動を減らせる

SORTKEY の戦略とクエリパターンへの当てはめ

SORTKEY はテーブルの物理的な並び順を定義します。COMPOUND は先頭列の並びを最優先し、先頭列での範囲フィルタ、ソート、グループ化の I/O を大きく減らせます。INTERLEAVED は複数列を均等に重視しますが、更新やスキューに敏感でメンテナンスの複雑さが増します。多くの分析系ワークロードでは COMPOUND が扱いやすく、最も頻出のフィルタ列を先頭に置くのが基本です。

ソートキーは結合キーと同一である必要はありません。よく使う時間列を先頭に、続いて選択性の高い列を配置します。ソートキーを指定しない場合、テーブルは挿入順となり、範囲フィルタのスキャン効率は落ちやすくなります。

  • 時間で絞り込むダッシュボードが多いなら、最初の SORTKEY に日時列を置く
  • 多次元の等価フィルタを同程度に使う特殊ケースでのみ INTERLEAVED を検討する
  • 更新が多いテーブルは、メンテナンス負荷を見越してシンプルなキーにする
種類向いているクエリ主な特徴・注意点
COMPOUND先頭列での範囲フィルタ、ORDER BY、GROUP BY先頭列の並びを最重視。一般的な分析に適合しやすい。列順の設計が重要
INTERLEAVED複数列を同程度に用いた等価フィルタが頻発各列を均等に重視。更新やスキューに敏感で運用複雑度が上がりやすい
未指定(ソートなし)全面スキャンでも十分に速い小〜中規模テーブル挿入順。範囲条件での I/O 削減効果は得にくい

dbt での設定方法とモデル設計パターン

dbt-redshift のモデルでは、diststyle、dist、sort、sort_type を config で宣言します。これらは CREATE TABLE の DDL に反映され、同じモデル名での再実行でも安定した物理設計を再現できます。ビューには適用されません。

ソートキーは列順が意味を持つため、クエリ頻度と選択性に基づいて順序を決めます。分散は事実テーブルの主結合キーに合わせるのが定石です。設定を変える場合、特に SORTKEY はテーブル再作成が必要になることがあるため、フルリフレッシュ計画とあわせて扱います。

  • 設定は materialized='table'(および incremental の最終テーブル)に適用される
  • ビューには dist/sort は効かない。必要なら下流でテーブル化する
  • DISTSTYLE を明示しない場合はデフォルト(多くの環境で AUTO)になる
  • SORTKEY を指定しなければソートなしで作成される。必要なら後日フルリフレッシュで付与する

dbt モデル例: 典型的なファクトテーブルの dist/sort

{{
  config(
    materialized='incremental',
    unique_key='order_id',
    diststyle='key',        # KEY/ALL/EVEN/AUTO から選択
    dist='customer_id',     # DISTKEY 列
    sort_type='compound',   # compound または interleaved
    sort=['order_ts', 'customer_id']  # 列順は重要
  )
}}

with src as (
  select * from {{ ref('stg_orders') }}
)

select
  order_id,
  customer_id,
  order_ts,
  total_amount
from src

{% if is_incremental() %}
  -- 例: 増分条件。ソート先頭列に合わせて範囲条件を使うと効きやすい
  where order_ts > (select coalesce(max(order_ts), '1970-01-01') from {{ this }})
{% endif %}

変更管理: 既存テーブルの DIST/SORT を見直すとき

DISTSTYLE の変更は環境により ALTER TABLE で対応できる場合がありますが、SORTKEY の列や種類の変更は、一般にテーブル再作成とデータ再投入が安全です。dbt では --full-refresh を使い、CTAS で新テーブルを作ってリネームする流れが確実です。

本番でのリスクを抑えるには、影響範囲の小さいモデル単位に分割し、段階的に切り替えます。再作成に時間がかかる大規模テーブルは、夜間ウィンドウやクラスターの一時的なスケールアップも検討します。

  • 変更は計測とロールバック計画とセットで行う
  • フルリフレッシュ前に対象モデルだけを限定実行して検証する
  • 下流依存を catalog とドキュメントで洗い出し、周知する

試験で問われやすい要点チェックリスト

dbt Analytics Engineer の文脈では、ワークロードに対してどの dist/sort を選ぶか、そしてそれを dbt の設定で正しく表現できるかが問われます。スター・スキーマの事実テーブルとディメンションの組み合わせで、コロケーション結合と範囲フィルタ最適化を説明できるようにしておきましょう。

  • 大規模ファクト × 小規模ディメンション: ファクトは DISTSTYLE KEY(主結合列)、ディメンションは ALL
  • 時間軸でのダッシュボード: SORTKEY は COMPOUND の先頭に日時列
  • 明確な結合キーがない中規模テーブル: EVEN か AUTO から開始
  • ビューには dist/sort が効かないため、最終的にテーブル化したモデルで最適化する
  • 設定変更はフルリフレッシュ前提で計画する

問題で確認

Analytics Engineer

問題 1

数億行規模の fact_orders を中心としたスター・スキーマ。ダッシュボードは日付範囲での集計が多く、fact_orders は dim_customers と customer_id で頻繁に結合される。最も適切な dbt 設定はどれか。

  1. fact_orders を diststyle='key'、dist='customer_id'、sort_type='compound'、sort=['order_ts','customer_id'] とする。dim_customers は diststyle='all'。
  2. fact_orders を diststyle='even'、sort_type='interleaved'、sort=['customer_id','order_ts'] とする。dim_customers は diststyle='even'。
  3. fact_orders を diststyle='all'、ソートなし。dim_customers は diststyle='all'。
  4. fact_orders を diststyle='key'、dist='event_id'、sort_type='compound'、sort=['customer_id'] とする。dim_customers は diststyle='auto'。

正解: A

主結合キーでのコロケーションを確保するために fact を DISTKEY=customer_id、範囲フィルタに強い COMPOUND の先頭に日時列を置くのが定石。小さなディメンションは ALL でブロードキャストを避ける。その他の選択肢は、データ移動やスキャン効率の点で不利。

よくある質問

dbt の dist/sort 設定と Redshift の自動最適化はどちらが優先される?

dbt で明示した diststyle/dist/sort は CREATE TABLE の DDL に反映されます。明示指定を採用した場合、その設定が基本となります。自動最適化の影響や具体的な挙動はクラスター設定やバージョンに依存するため、AUTO を使うか明示するかはワークロードに合わせて選び、実測で確認してください。

環境ごとに dist/sort を変えたい。dbt でどう管理する?

dbt_project.yml の models セクションで target.name 条件を使い、開発は diststyle='auto'、本番は明示指定、のように切り替えられます。モデル内の Jinja で変数や env_var を参照して設定を分岐させる方法も現実的です。

ビューやマテリアライズド・ビューで dist/sort は使える?

ビューには適用されません。dbt の dist/sort 設定はテーブル作成時に有効です。マテリアライズド・ビューに関する取り扱いは実装やバージョンに依存しますが、一般に dist/sort を明示的に指定する前提では設計しない方が安全です。必要な最適化は最終テーブルで行うのが確実です。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
dbt

dbt Model の基礎: SQL で定義する変換の最小単位

Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...

dbt

dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点

dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...

dbt

dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点

dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...

dbt

dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト

Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....

dbt

dbt_project.yml の読み方:主要設定と命名を最短で掴む

dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...

dbtの記事一覧 (100件)
© 2026 NicheeLab All rights reserved.