すべてのプロダクト
Search
ドキュメントセンター

PolarDB:CCIを作成するためのガイドライン

最終更新日:Oct 12, 2024

このトピックでは、特定のシナリオでテーブルのクラスター化円柱インデックス (CCI) を作成して、クエリのパフォーマンスを向上させるためのガイドラインについて説明します。

シナリオ

重要

CCIは、一貫したクエリ結果を確保するために、変更データキャプチャ (CDC) ノードに基づいて非同期に構築されます。 ただし、プライマリインスタンスから列ストア読み取り専用インスタンスにデータが同期されると、第2レベルのレイテンシが発生します。 したがって、リアルタイムのデータアクセスが重要なシナリオでは、CCIを使用しないことをお勧めします。

  1. 異なるクエリワークロードを伴う、または複雑なクエリの高速化が必要なシナリオ

    説明

    CCIは、複雑な分析処理 (AP) クエリのパフォーマンスを大幅に向上させることができます。

  2. コールドデータのアーカイブシナリオ

    説明

    列ストア読み取り専用ノード (計算ノード) は、Object Storage Service (OSS) に保存されているCCIデータを使用してメタデータにアクセスできます。 したがって、columnインデックスを使用してOSSにコールドデータを保存し、ストレージコストを削減できます。 詳細は、「TTL」をご参照ください。

  3. 履歴スナップショットを保存して照会するシナリオ

    説明

    CCIは、履歴データの有効期限が切れないレプリカとして機能します。 履歴スナップショットを保持およびクエリできます。 この機能は、監査およびバックアップビジネスで一般的に使用されます。

  4. ETLシナリオ

    説明

    CCIは、プライマリインスタンスのデータレプリカとして機能します。 CCIを使用してデータの抽出、変換、読み込み (ETL) を実行し、データを別のシステムに転送するカラムストア読み取り専用インスタンスに接続できます。

パーティション分割されたテーブル

一般的なパーティション分割方法

パーティション化は、大きなテーブルをより小さく管理しやすい部分に分割するために使用される方法です。これにより、大きなデータセットのクエリのパフォーマンスとデータ管理効率が向上します。 CCIを分割するための構文:

PARTITION BY
HASH({column_name | partition_func(column_name)})
| KEY(column_list)
| RANGE({column_name | partition_func(column_name)})
| RANGE COLUMNS(column_list)
| LIST({column_name | partition_func(column_name)}) 
| LIST COLUMNS(column_list)} }
説明
  • 範囲分割 (Range): 列の値の範囲に基づいてデータを分割します。 たとえば、テーブルに履歴売上データが格納されている場合、テーブルを売上年ごとに分割して、同じ年のすべてのレコードを同じパーティションに配置できます。

  • リストパーティショニング (List): 列内の値が定義済みの値のセットに含まれるかどうかに基づいてデータをパーティション化します。 この分割方法は、サービスとしてのソフトウェア (SaaS) シナリオで一般的に使用されています。 たとえば、ユーザーデータテーブルを国ごとに分割して、同じ国のユーザーデータを同じパーティションに配置できます。

  • ハッシュ分割 (Hash /KEY): 列のハッシュ値に基づいてデータを分割します。これにより、パーティション間でデータをより均等に分散できます。 ハッシュパーティショニングは、データ分散が予測できない、またはデータ分散が必要なシナリオに適しています。

  • 詳細については、「パーティションタイプ」をご参照ください。

パーティション数を設定するためのガイドライン

理論的には、パーティションの数は、テーブルの数と列ストア読み取り専用インスタンスの仕様に基づいて決定されます。 デフォルトでは、パーティションの数は16です。 デフォルトのパーティション数を使用しないことを推奨します。 一般的なガイドラインでは、次の式を使用してパーティションの数を計算します。コンピューティングノードの数 × コンピューティングノードのコアの数。 潜在的なデータ成長のために、上記の式を使用して計算された数値よりも大きい数値を指定できます。

説明

複数のテーブルを結合する操作を実行する場合は、同じインスタンス内の関係するテーブル間でパーティションの数を一致させることを推奨します。

パーティション分割方法を選択するためのガイドライン

  • CCIは主にAPクエリのパフォーマンスを向上させるように設計されており、ほとんどの場合、集計と結合操作が含まれます。 列型ストレージの並列スキャンとクエリの利点を十分に活用するには、ハッシュパーティション分割を使用することを推奨します。

  • 時間関連のクエリの場合、関連する時間列を使用してサブパーティションを作成します。 クエリが時間関連の条件に大きく依存しない他のシナリオでは、必要でない限りCCIのサブパーティションを作成しないでください。 詳細については、「サブパーティショニング」をご参照ください。

  • クエリするデータが特定の範囲に基づいていない場合は、範囲パーティション分割を使用しないことを推奨します。 クエリするデータが定義済みの値のリストに基づいていない場合は、リストパーティションを使用しないことをお勧めします。 クエリするデータが範囲またはリストのパーティション分割に適している場合でも、クエリ要件を満たすように行指向のストレージに優先順位を付けることをお勧めします。

  • ビジネスがCCIに基づいてコールドデータをアーカイブする場合は、時間列に基づいた範囲パーティション分割を使用することを推奨します。

パーティションキーを選択するためのガイドライン

  • 値が均等に分散されている列をパーティションキーとして選択します。 たとえば、トランザクションID列、デバイスID列、ユーザーID列、または自動インクリメント列を選択できます。

    説明

    日付、時刻、またはtimestamp列をパーティションキーとして使用しないことを推奨します。 書き込みのほとんどが同じ日または期間に集中している場合、時間ベースのパーティションキーを使用すると、データが同じパーティションに蓄積される可能性があります。 これは、性能の低下につながり得ます。 ほとんどのクエリは、前日または月のレコードなど、特定の時間範囲に焦点を当てています。 時間ベースのキーを使用すると、その特定の日付または時間範囲のデータを格納する単一のノード上のデータにアクセスできます。 その結果、データベースの分散性が有効に利用されない。 クエリに日付または時刻列が必要な場合は、日付または時刻列をサブパーティションキーとして使用できます。

  • パーティションキーとして、JOINまたはGROUP BY操作に頻繁に関与する列を選択します。 これにより、データ再配布のオーバーヘッドを最小限に抑えることができます。 たとえば、顧客別の注文履歴データを分析する場合は、顧客ID列をパーティションキーとして使用できます。

  • 範囲外のクエリ条件で頻繁に使用される列をパーティションキーとして選択し、キーに基づいてデータのプルーニングを有効にします。

  • 各テーブルには、1つ以上のフィールドで構成できるパーティションキーを1つだけ持つことができます。 パーティションキーのフィールドが少ないと、複雑なクエリシナリオでのキーの適応性が向上します。

重要
  • テーブルを作成するときにパーティションキーを指定しない場合、システムはプライマリキーをパーティションキーとして使用します。 明示的な主キーがない場合、システムは暗黙的な主キーをパーティションキーとして使用します。

  • テーブルのCCIを作成した後、check columnar partition db_name.tbl_nameステートメントを実行して、パーティション間のデータ分布を確認できます。 これにより、パーティションキーが適切かどうかを確認し、潜在的なデータスキューを特定できます。

ソートキー

概要

CCIのソートキーは、データがCCIファイル内でどのようにソートされるかを決定します。 各列データブロックのメタデータは、列データブロック内の全てのデータの最小値及び最大値を含みます。 データをクエリすると、クエリに含まれるすべての列データブロックがスキャンされます。 Prunerを有効にすると、Prunerは、クエリ条件とメタデータに基づいて、列データブロックを3つのカテゴリに分類します。 関連する可能性のある列データブロックのみがクエリのためにスキャンされます。 列データブロックは異なる順序でソートすることができ、これはデータの異なる組み合わせにつながります。 Prunerのフィルタリングは、データ配置に基づいて異なります。 クエリ条件を変更して、データブロックのソート方法を変更できます。 これにより、クエリのパフォーマンスが向上します。 プルーナー機能の詳細については、「IMCIベースのクエリのフィルターアルゴリズムの設定」をご参照ください。

image

ソートキーを選択するためのガイドライン

  • 特定の列の値の範囲に基づいてテーブルが頻繁にクエリされるシナリオでは、その列をソートキーとして使用することをお勧めします。

  • データがページで取得されるシナリオでは、ORDER BY句で指定された列をソートキーとして使用することをお勧めします。

  • 他のシナリオでは、パーティションキーをソートキーとして使用することを推奨します。

辞書エンコーディング

概要

ディクショナリエンコーディングは文字列値を数値に変換します。これにより、GROUP BYやFILTERなどの操作を大幅に高速化し、データ圧縮率を向上させ、ストレージコストを削減できます。 PolarDB-Xでは、CCIを作成してフィールドの値の辞書マッピングを作成するときに、特定のフィールドを辞書エンコードできます。 例:

# Specify columns col1 and col2 for dictionary encoding.
DICTIONARY_COLUMNS='col1,col2';
# Explicitly create a CCI on a table and specify columns for dictionary encoding.
CREATE CLUSTERED COLUMNAR INDEX `cc_i_seller` ON t_order (`seller_id`) partition by hash(`order_id`) partitions 16
dictionary_columns='order_id,seller_id';

辞書エンコーディングの列を選択するためのガイドライン

  • 異なる値がほとんどない性別や地域の列など、ディクショナリのエンコーディングにはカーディナリティの低い列を選択することをお勧めします。

  • 追加のエンコードとデコードのオーバーヘッドを防ぐため、すべての文字列に辞書エンコードを適用しないことをお勧めします。

説明

カーディナリティが小さい辞書エンコード列は、データを圧縮してストレージスペースを節約し、クエリのパフォーマンスを向上させることができます。 しかしながら、分散型データベースにおけるクエリは、辞書の構文解析およびマージを伴います。 これは追加のオーバーヘッドを引き起こす可能性があります。 したがって、辞書ベースのクエリは、クエリプロセス中に自動的に無効になります。 辞書ベースのクエリを有効にするには、ENABLE_COLUMNAR_SLICE_DICTパラメーターをTRUEに設定します。

よくある質問

  1. クラスターの仕様を変更すると、パーティションの数が影響を受けますか。

    いいえ。

  2. CCIのパーティションキー、ソートキー、パーティション数、および辞書でエンコードされた列を変更できますか?

    いいえ。 CCIのパーティションキー、ソートキー、パーティション数、および辞書でエンコードされた列を変更するには、CCIを削除してからCCIを再作成します。

  3. CCIを作成するには、カラムストア読み取り専用インスタンスを購入する必要がありますか?

    プライマリインスタンスにCCIを作成できます。 CCIデータをクエリするには、列ストア読み取り専用インスタンスを購入することを推奨します。