mcpField
D
doris-best-practices

doris-best-practices

github.com/apacheデータ・データベース47119 回インストール4 週間前に更新
リポジトリ

doris-best-practices について

doris-best-practicesは、Apache Dorisのテーブル設計、クエリ調査、クラスター容量設計を支援するスキルです。ワークロード別のルールやテンプレートに加え、DDL制約と証拠に基づく診断手順をまとめています。

主な機能

  1. 01ワークロード別のテーブル設計テンプレート
  2. 02CREATE TABLE前のチェックリスト
  3. 03DDLの制約と注意点
  4. 04証拠に基づくクエリ診断手順
  5. 05FE、BE、ストレージの容量設計ガイド

活用シーン

  1. 01ログ、CDC、ダッシュボード向けテーブル設計
  2. 02キー、パーティション、バケット、インデックスの選択
  3. 03profileやEXPLAINによる低速クエリの調査
  4. 04クラスターとストレージの容量見積もり

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/apache/doris-skills --skill doris-best-practices

インストール後、Claude Code で/doris-best-practicesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
cli-investigation.md
schema-bucket-cloud-mandatory-hash.md
schema-bucket-composite-for-skew.md
schema-bucket-hash-vs-random.md
schema-bucket-high-cardinality-key.md
schema-bucket-target-size.md
schema-cache-file-cache.md
schema-cache-query-partition.md
schema-ddl-gotchas.md
schema-index-bitmap.md
schema-index-bloomfilter.md
schema-index-inverted.md
schema-index-ngram-for-like.md
schema-index-text-search.md
schema-index-vector.md
schema-keys-avoid-float.md
schema-keys-cluster-key-for-mow.md
schema-keys-fixed-length-types.md
schema-keys-prefix-index-limits.md
schema-keys-selectivity-first.md
schema-model-avoid-agg-for-updates.md
schema-model-choose-for-workload.md
schema-model-prefer-mow.md
schema-model-sequence-col-for-cdc.md
schema-mv-async-join.md
schema-mv-async-limits.md
schema-mv-sync-rollup.md
schema-partition-auto-on-demand.md
schema-partition-dynamic-ttl.md
schema-partition-range-for-timeseries.md

詳細

Apache Doris のベストプラクティス

Apache Doris 向けの、課題起点のテーブル設計インテリジェンスです。 37 個のルール、7 個のユースケーステンプレート、4 個のサイジングガイドを収録しています。 詳細はすべて references/ ディレクトリにあります。


1 ▸ 課題起点のルーティング

構築したいもの…
課題テンプレート主なルール
リアルタイムのログ/イベント分析usecase-log-eventDUPLICATE、RANGE パーティション、動的 TTL、ZSTD
CDC/MySQL から Doris への同期usecase-cdc-syncUNIQUE MoW、sequence_col、HASH バケット
事前集計済みメトリクスを使うダッシュボードusecase-dashboard-metricsAGGREGATE、BITMAP_UNION、同期 MV
低レイテンシのポイントクエリを使うユーザー向け APIusecase-point-queryUNIQUE MoW、store_row_column、BloomFilter
JOIN を多用する分析向けのスター・スキーマusecase-star-schema-joinコロケーション、同じバケットキー/数
小規模なディメンション/ルックアップテーブルusecase-dimension-lookupDUPLICATE、RANDOM バケット、3 バケット
オブザーバビリティ(ログ+トレース+メトリクス)usecase-observability3 つのテーブル:DUP ログ、DUP トレース、AGG メトリクス
車両/フリートのトラッキングusecase-log-event + usecase-point-query時系列とポイントクエリのハイブリッド
E コマースの注文分析usecase-star-schema-join + usecase-dashboard-metricsスター・スキーマ+AGG ロールアップ
全文検索/コンテンツ検索schema-index-text-search転置インデックス、MATCH、BM25
ユーザー行動/ファネル分析schema-types-bitmap-count-distinctBITMAP_UNION、bitmap_intersect
半構造化 JSON データschema-types-variant-jsonVARIANT 型、schema_template
証拠から次の状況がわかり、クエリが遅い場合…

実行中のスロークエリやランタイムの診断では、最初の対応としてこの表を使用しないでください。まず references/cli-investigation.md を読み、証拠を収集するか、収集を試みてください(profile get、profile list、profile history、tablet、EXPLAIN、または auth status)。この表は、証拠から症状が特定できた場合にのみ使用してください。

症状確認するルールすぐにできる修正
WHERE 句でテーブル全体がスキャンされるschema-keys-selectivity-firstフィルター対象の列をソートキーの先頭に移動する
JOIN が遅い/シャッフルが発生するusecase-star-schema-join小規模なディメンション(<1GB):ブロードキャスト+ランタイムフィルター。大規模な場合:コロケーション
COUNT DISTINCT が遅いschema-types-bitmap-count-distinctBITMAP_UNION 集計に切り替える
LIKE '%keyword%' が遅いschema-index-ngram-for-likeNGram BloomFilter インデックスを追加する
ポイントクエリのレイテンシが高すぎるusecase-point-querystore_row_column と Prepared Statement を有効にする
ストレージの増加が速すぎるschema-partition-auto-on-demand + schema-props-compressionAUTO PARTITION+ZSTD 圧縮+DROP PARTITION の定期実行
同期 MV が使用されないschema-mv-sync-rollupMV の GROUP BY では date_trunc ではなく生の列を使用する。一意なエイリアスを指定する
非同期 MV の書き換えに失敗するschema-mv-async-join + schema-mv-async-limitsState/RefreshState を確認する。述語が一致しない場合は MV を直接クエリする
データの偏り/ホットタブレットschema-bucket-composite-for-skew複合バケットキーまたは RANDOM を使用する
インポート失敗/データバージョンエラーschema-mv-async-limitsMV の同時リフレッシュ上限(最大 3)を確認する
キー内の VARCHAR がパフォーマンスを低下させるschema-keys-fixed-length-typesVARCHAR を固定長型の後ろに移動する
UNIQUE テーブルへの書き込みが遅いschema-model-prefer-mowMoW が有効(MoR ではない)ことを確認する

2 ▸ フライト前チェックリスト(CREATE TABLE の前に必ず確認)

このチェックリストを順番に確認してください。各項目には該当するルールが記載されています。

  • データモデル — UNIQUE(更新しますか?)か DUPLICATE(追記しますか?)か AGGREGATE(事前集計のみですか?)→ schema-model-choose-for-workload
  • パーティション戦略 — 時系列データですか? AUTO PARTITION を推奨します。小さなテーブルですか?省略します。AUTO と dynamic_partition を併用しないでください。→ schema-partition-*
  • バケットキーと数 — JOIN キーに HASH を使用します。明示的な数を計算します:daily_GB / target_tablet_GB。ボリュームが不明な場合は、明示的なフォールバック数を使用します:小規模ディメンションは 3、中規模テーブルは 8、大規模な日次ファクトテーブルは 16-32。→ schema-bucket-*
  • ソートキーの順序 — 選択性の高いものを先にし、固定長の列を VARCHAR より前にします → schema-keys-*
  • データ型 — STRING ではなくネイティブ型を使用します。FLOAT ではなく DECIMAL を使用します。→ schema-types-*
  • インデックス — 等価検索には BloomFilter、テキストには Inverted、LIKE には NGram を使用します → schema-index-*
  • プロパティ — MoW は有効ですか?圧縮は設定されていますか?クラウドモードの replication_num=1 は設定されていますか?→ schema-props-*
  • DDL の厳格な制約(いずれかに違反すると Apache Doris は DDL を拒否します):
    • UNIQUE KEY + PARTITION BY RANGE の場合、パーティション列は UNIQUE KEY に必ず含める必要があります:UNIQUE KEY(id, dt) PARTITION BY RANGE(dt)
    • キー列はスキーマの最初の N 列で、同じ順序でなければなりません。キー列を先に、非キー列を後に配置します。例:UNIQUE KEY(account_id, symbol) の場合、スキーマは account_id, symbol, ... で始める必要があります。キー列の間に非キー列を配置しないでください
    • store_row_column = "true" は UNIQUE MoW と DUPLICATE で動作しますが、AGGREGATE では動作しません(Doris は AGG を拒否します:「Aggregate table can't support row column」)。4.x で確認済みです。旧バージョンでは UNIQUE のみ対応していました
    • AUTO PARTITION には date_trunc() と空のかっこが必要です:AUTO PARTITION BY RANGE(date_trunc(col, 'day')) () — 列名のみでは失敗し、() がない場合も失敗します
    • Dynamic partition には、DDL に明示的な PARTITION BY RANGE(col) () 句が必要です。プロパティだけでは不十分です
    • dynamic_partition.buckets は設定しないでください。数値は DISTRIBUTED BY HASH(col) BUCKETS N にのみ指定します
    • compaction_policy = "time_series" は DUPLICATE テーブルでのみ使用できます。UNIQUE では失敗します
    • 非同期 MV 更新には、REFRESH AUTO ON SCHEDULE EVERY 10 MINUTE または REFRESH COMPLETE ON SCHEDULE EVERY 10 MINUTE を使用します。REFRESH SCHEDULE EVERY や REFRESH ASYNC EVERY(INTERVAL ...) は使用しないでください。最小間隔は 1 MINUTE です
    • NOW()/CURDATE() を使用する MV では、PROPERTIES ("enable_nondeterministic_function" = "true") を追加します
    • BOOLEAN のデフォルト値は引用符で囲む必要があります:DEFAULT "true"。DEFAULT TRUE ではありません
    • BloomFilter インデックスには PROPERTIES ("bloom_filter_columns" = "col1,col2") を使用します。インラインの INDEX ... USING BLOOM FILTER は使用しないでください
    • AGGREGATE の列構文では、デフォルト値より前に集計関数を指定します:col BIGINT SUM DEFAULT "0"。col BIGINT DEFAULT "0" SUM ではありません
    • AGGREGATE の DEFAULT "null" は VARCHAR でのみ動作します。INT、DATE、DECIMAL、BIGINT では失敗します。文字列以外の型で REPLACE_IF_NOT_NULL を使用する場合は、DEFAULT を完全に省略します:vip_level INT REPLACE_IF_NOT_NULL(DEFAULT "null" は指定しません)
    • enable_unique_key_partial_update はセッション変数であり、テーブルプロパティではありません
    • 詳細:schema-ddl-gotchas

2b ▸ DDL テンプレート(最も近いものをコピーし、列をカスタマイズ)

CREATE TABLE ごとに、以下から最も近いテンプレートを選択してください。列名、型、バケット数、パーティション設定をカスタマイズします。DDL を一から記述しないでください。

T1: 追記専用イベント/ログ(DUPLICATE)
CREATE TABLE events (
    entity_id    VARCHAR(64)  NOT NULL,
    event_time   DATETIME     NOT NULL,
    event_type   VARCHAR(50)  NOT NULL,
    payload      VARIANT
) DUPLICATE KEY(entity_id, event_time, event_type)
PARTITION BY RANGE(event_time) ()
DISTRIBUTED BY HASH(entity_id) BUCKETS 10
PROPERTIES (
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-90",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "compression" = "zstd",
    "compaction_policy" = "time_series",
    "replication_num" = "1"
);
T2: パーティション付きの更新可能なデータ(UNIQUE MoW + CDC)
CREATE TABLE orders (
    order_id     BIGINT       NOT NULL,
    order_time   DATETIME     NOT NULL,
    update_time  DATETIME     NOT NULL,
    status       VARCHAR(20),
    amount       DECIMAL(18,2)
) UNIQUE KEY(order_id, order_time)
PARTITION BY RANGE(order_time) ()
DISTRIBUTED BY HASH(order_id) BUCKETS 5
PROPERTIES (
    "enable_unique_key_merge_on_write" = "true",
    "function_column.sequence_col" = "update_time",
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-365",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "replication_num" = "1"
);
T3: 小規模ディメンション/ルックアップ(UNIQUE、パーティションなし)
CREATE TABLE dim_product (
    product_id   INT          NOT NULL,
    name         VARCHAR(200),
    category     VARCHAR(50)
) UNIQUE KEY(product_id)
DISTRIBUTED BY HASH(product_id) BUCKETS 3
PROPERTIES (
    "enable_unique_key_merge_on_write" = "true",
    "replication_num" = "1"
);
T4: 事前集計済み KPI(AGGREGATE)
CREATE TABLE daily_kpi (
    stat_date    DATE         NOT NULL,
    dimension    VARCHAR(50)  NOT NULL,
    metric_sum   BIGINT       SUM DEFAULT "0",
    metric_max   DOUBLE       MAX DEFAULT "0",
    unique_users BITMAP       BITMAP_UNION
) AGGREGATE KEY(stat_date, dimension)
PARTITION BY RANGE(stat_date) ()
DISTRIBUTED BY HASH(dimension) BUCKETS 3
PROPERTIES (
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "MONTH",
    "dynamic_partition.start" = "-12",
    "dynamic_partition.end" = "1",
    "dynamic_partition.prefix" = "p",
    "replication_num" = "1"
);
T5: ポイントクエリ/API サービング(UNIQUE MoW + row store)
CREATE TABLE user_profiles (
    user_id      BIGINT       NOT NULL,
    update_time  DATETIME     NOT NULL,
    name         VARCHAR(100),
    data         VARIANT
) UNIQUE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 5
PROPERTIES (
    "enable_unique_key_merge_on_write" = "true",
    "function_column.sequence_col" = "update_time",
    "store_row_column" = "true",
    "light_schema_change" = "true",
    "replication_num" = "1"
);

3 ▸ 接続と CLI

Apache Doris は MySQL プロトコルに対応しているため、常に利用可能な方法として、MySQL 互換クライアント(mysql)と SQL、FE HTTP REST API を使用できます。一部のディストリビューションには、プロファイリングや診断用の便利なコマンドを追加するオプションの管理 CLI(ここでは doriscli と呼びます)も含まれています。ディストリビューションで提供されている場合はこれを使用し、提供されていない場合はネイティブの方法を使用してください。

オプションの CLI を検出する

クエリを実行する前に、CLI バイナリが利用可能かどうかを検出してください。

  1. DORIS_CLI_PATH 環境変数を確認します。設定されている場合は、そのバイナリパスを使用します
  2. command -v doriscli を実行します。PATH 上にあるものを使用します
  3. どちらも利用できない場合は、mysql クライアントにフォールバックします(references/start-*.md を参照)
doriscli が利用可能な場合は、すべての操作で優先して使用してください。
タスクdoriscli コマンド
SQL の実行doriscli sql "SELECT ..."
DDL の確認doriscli sql "SHOW CREATE TABLE db.t"
テーブル/タブレットの健全性確認doriscli tablet db.t(概要)または doriscli tablet db.t --detail
遅いクエリのプロファイリングdoriscli sql "SELECT ..." --profile → query_id を取得
クエリプロファイルの取得doriscli profile get <qid>、または完全な診断には --full
高速クエリと低速クエリの比較doriscli profile diff <slow_qid> <fast_qid>
パフォーマンスの推移doriscli profile history <sql_pattern> --days 7
接続のテストdoriscli auth status
環境の切り替えdoriscli use <name>
実行時のクエリ調査

遅いクエリや実行時のパフォーマンス問題については、references/cli-investigation.md を読んでください。

  • 証拠の収集が必須です:仮説を立てる前に、プロファイル、タブレット、DDL、統計情報、EXPLAIN、履歴、実行中のクエリ、または接続の証拠を収集するか、収集を試みてください。ローカルで証拠を収集できない場合は、その旨を伝え、実行する正確なコマンドを提示してください
  • 既存のプロファイルを優先してください:SQL を再実行する前に、profile get <query_id>、profile list、または profile history を使用してください
  • 積極的に情報を確認してください:遅いクエリについて曖昧な報告を受けた場合は、ユーザーに詳細を尋ねる前に、auth status、profile list --active、および最近の profile list から開始してください
  • 安全性の確認:ユーザーの SQL を --profile 付きで実行する前に、安全かどうかを確認してください(DDL がなく、データ変更がなく、範囲に制限のないスキャンでないこと)。SQL が不明な場合、ピーク時間帯の場合、または負荷が高い場合は、まず doriscli sql "EXPLAIN <query>" --format json を実行し、確認を求めるか既存の query_id を提示してもらってください
  • 断定ではなく仮説を示してください:診断上の対応付けはヒューリスティックです。証拠、考えられる原因、次に確認すべき点、結論が誤っている可能性がある状況を提示してください
  • doriscli が利用できない場合は、リファレンスに記載された SQL コマンドにフォールバックしてください
  • 構造化されたエージェント可読形式の出力には、必ず --format json を使用してください
クイックスタートガイド
  • references/start-self-hosted.md — セルフホスト/BYOC/オンプレミス
  • クラウドモード(ストレージとコンピュート)では HTTP ポート(8080 と 8030)が異なるだけです。同じガイドを使用できます

4 ▸ クラスターのサイジング

サイジングガイド:

  • references/sizing-fe.md — FE ノードのサイジング
  • references/sizing-be-integrated.md — BE のサイジング(統合ストレージ)
  • references/sizing-be-cloud.md — BE のサイジング(クラウド/ストレージとコンピュート)
  • references/sizing-storage-formula.md — ストレージ計算式

5 ▸ カテゴリ別ルールインデックス

データモデル — 重要(4 ルール)
  • schema-model-choose-for-workload — DUP、UNIQUE、AGG の選択フローチャート
  • schema-model-prefer-mow — UNIQUE テーブルでは常に MoW を使用
  • schema-model-avoid-agg-for-updates — AGG では UPDATE/DELETE を実行できません
  • schema-model-sequence-col-for-cdc — 順不同の CDC に使用するシーケンス列
パーティション戦略 — 重要(4 ルール)
  • schema-partition-range-for-timeseries — 時系列データには RANGE を使用
  • schema-partition-dynamic-ttl — TTL の自動化には動的パーティションを使用
  • schema-partition-auto-on-demand — 断続的なデータには AUTO を使用
  • schema-partition-skip-for-small — 1 GB 未満ではパーティション分割を省略
バケット戦略 — CRITICAL(5 つのルール)
  • schema-bucket-hash-vs-random — プルーニングには HASH、DUP のみに RANDOM を使用します
  • schema-bucket-high-cardinality-key — カーディナリティの高いカラムを選択します
  • schema-bucket-composite-for-skew — データの偏りを解消するには複合キーを使用します
  • schema-bucket-target-size — タブレットあたり 1~10 GB を目標にします
  • schema-bucket-cloud-mandatory-hash — Cloud MoW では HASH が必須です
ソートキー — CRITICAL(5 つのルール)
  • schema-keys-selectivity-first — 選択性の高いものを先にします
  • schema-keys-fixed-length-types — VARCHAR より固定長の型を先にします
  • schema-keys-prefix-index-limits — 最大 36 バイトで、VARCHAR が終端になります
  • schema-keys-cluster-key-for-mow — UNIQUE テーブルにはクラスタキーを使用します
  • schema-keys-avoid-float — ソートキーに FLOAT/DOUBLE を使用しません
データ型 — HIGH(5 つのルール)
  • schema-types-native-vs-string — STRING ではなく、ネイティブ型を使用します
  • schema-types-zonemap-limitations — JSON/ARRAY は ZoneMap を無効にします
  • schema-types-variant-json — 半構造化 JSON には VARIANT を使用します
  • schema-types-bitmap-count-distinct — 正確な個別値カウントには BITMAP_UNION を使用します
  • schema-types-doris-specifics — DATETIME の精度、VARCHAR と STRING の違い
インデックス — HIGH(7 つのルール)
  • schema-index-bloomfilter — 等価比較には BloomFilter を使用します
  • schema-index-inverted — テキストや範囲検索には転置インデックスを使用します
  • schema-index-ngram-for-like — LIKE %pattern% には NGram を使用します
  • schema-index-bitmap — 中程度のカーディナリティには Bitmap を使用します
  • schema-index-vector — ANN 検索には HNSW/IVF を使用します
  • schema-index-text-search — 全文検索には MATCH と BM25 を使用します
クエリアクセラレーション — HIGH(3 つのルール)
  • schema-mv-sync-rollup — 単一テーブルの集計には同期 MV を使用します
  • schema-mv-async-join — 複数テーブルの JOIN には非同期 MV を使用します
  • schema-mv-async-limits — 運用上の制限(5000 万行、同時実行 3 件)
テーブルプロパティ — HIGH/MEDIUM(2 つのルール)
  • schema-props-cloud-forced — Cloud モードで強制されるプロパティ
  • schema-props-compression — LZ4 と ZSTD の圧縮
キャッシュ — MEDIUM(2 つのルール)
  • schema-cache-file-cache — Cloud モードにはファイルキャッシュを使用します
  • schema-cache-query-partition — クエリキャッシュとパーティションキャッシュ

コメント