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

AnalyticDB:インデックスの最適化

最終更新日:Sep 27, 2024

AnalyticDB for PostgreSQLは、Bツリー、ビットマップ、BRIN、GiST、およびGINインデックスをサポートしますが、ハッシュインデックスはサポートしていません。 各タイプのインデックスは特定のアルゴリズムを使用し、特定のクエリタイプに適しています。 Bツリーインデックスは、最も一般的なシナリオに理想的なデフォルトのインデックスタイプです。

説明

サーバーレスモードのAnalyticDB for PostgreSQLでは、Bツリーインデックスのみを作成できます。

ほとんどのオンライントランザクション処理 (OLTP) データベースでは、インデックスによってクエリ効率が大幅に向上します。 ただし、AnalyticDB for PostgreSQLなどの分散データウェアハウスサービスでは、インデックスを慎重に選択する必要があります。 ほとんどのシナリオでは、AnalyticDB for PostgreSQLは高速なシーケンシャルスキャンに最適であり、スパースインデックスを使用してI/O操作を削減できます。 AnalyticDB for PostgreSQLは、それぞれが独自のデータのみをスキャンするすべての計算ノードにデータを均等に分散します。 AnalyticDB for PostgreSQLインスタンスに多数の計算ノードがある場合、各ノードは少量のデータのみをスキャンします。 大量のデータを返すBIレポートクエリの場合、インデックスはクエリを高速化できません。

AnalyticDB for PostgreSQLを使用する場合は、まずインデックスなしでクエリを実行することをお勧めします。 インデックスは、単一の行または少量のデータのみが返されるOLTPシナリオに適しています。 インデックスは、データ更新中に、ストレージの増加、書き込み増幅、インデックスのメンテナンスなど、追加のデータベースオーバーヘッドも発生します。 したがって、テーブル全体のスキャンよりもクエリ効率が高い場合にのみ、インデックスを作成することをお勧めします。

説明

AnalyticDB for PostgreSQLでは、インデックスキー列が配布キー列と同一またはスーパーセットである場合にのみ、一意のインデックスが許可されます。 追加最適化 (AO) テーブルは、一意のインデックスをサポートしていません。 一意のインデックスは、単一のパーティション内でのみ使用できます。 パーティションテーブルの異なるパーティション間では使用できません。

インデックスを作成する前に、次の項目に注意してください。

  • クエリのワークロードの測定: インデックスは、トランザクション処理クエリなど、単一の行または小さなデータセットを返すクエリのパフォーマンスを大幅に向上させることができます。

  • スパースインデックスが適切な圧縮テーブルまたは範囲クエリシナリオの決定: インデックスは、圧縮AOまたは追加最適化列指向 (AOCO) テーブルのクエリ効率を向上させることができます。 範囲クエリでは、スパースインデックスは無効なデータの読み込みを回避し、I/Oパフォーマンスを最適化できます。 データの読み込みが少ないとデータの解凍が少なくなり、解凍中のCPUの使用率が低下します。

  • 頻繁に更新される列にインデックスを作成しない: 特定の列でデータが頻繁に更新されると、インデックスも頻繁に更新され、データ更新のパフォーマンスが大幅に低下します。

  • インデックス選択率が高い列にのみBツリーインデックスを作成する: インデックス選択率は、インデックスタイプを選択するための重要な指標です。 B-treeインデックスは、インデックス選択率の高い列にのみ作成することをお勧めします。 たとえば、テーブルに1,000行のデータが含まれ、インデックスを作成する列に800の異なる値が含まれている場合、この列のインデックス選択率は800/1000 = 0.8です。 このシナリオでは、Bツリーインデックスが適しています。 インデックスを作成する列に一意の値がある場合は、B-treeインデックスを選択することを推奨します。

  • インデックス選択率の低い列にビットマップインデックスを作成する: ビットマップインデックスは、列が異なる値を100,000する1,000があるシナリオでAnalyticDB for PostgreSQLに最適です。 ソートキーを使用してデータを集計すると、ビットマップインデックスによりクエリが大幅に高速化されます。

  • 頻繁に結合される列にインデックスを作成する: インデックスをJOIN操作と一緒に使用して、クエリのパフォーマンスを向上させることができます。

  • 条件付きクエリが頻繁にある列にインデックスを作成する: WHERE句で頻繁に参照される列にインデックスを作成することを推奨します。

  • 同じ列に複数のインデックスを作成しない: 同じ列に同じタイプの複数のプレフィックスインデックスがあると、クエリのパフォーマンスが向上せず、書き込みおよび更新操作に追加のオーバーヘッドが発生する可能性があります。

  • ソートキーまたはCLUSTERステートメントを使用してインデックスの効率を向上させる: ほとんどのインデックス、特にBRINおよびスパースインデックスの効率は、データの物理的な分散の影響を受けます。 インデックスに基づくデータの適切な物理的分散により、インデックスのパフォーマンスが向上します。 複合ソートキーまたはインターリーブソートキーを使用して、より適切な方法でデータを配布できます。 行指向のテーブルにBツリーインデックスを作成する場合は、CLUSTERステートメントを実行して物理ソートを実装することを推奨します。

  • 大量のデータを処理するためのスパースインデックスの作成: テーブルに大量のデータが含まれており、<、<=、=、>=、> 演算子を使用して50% 未満のデータを取得する場合は、スパースインデックスを作成して、ロードされる無効なデータの量を減らすことができます。 スパースインデックスの例には、BRINインデックスとAOCOテーブルのメタデータ機能が含まれます。

  • 大量のデータをテーブルに読み込む前に、テーブルからインデックスを削除することをお勧めします。 データが読み込まれた後、テーブルのインデックスを再作成できます。 この方法は、インデックスの更新よりも高速です。

  • 頻繁に更新されるテーブルにビットマップインデックスを作成しない: ビットマップインデックスは、データが照会されても更新されないデータウェアハウスシナリオに最適です。 大量の同時トランザクションによってデータが変更されるOLTPシナリオには適用できません。

  • 適切な式インデックスの使用: インデックスキー列には、テーブルの列、またはテーブルの1つ以上の列から計算される関数またはスカラー式を使用できます。 この機能は、計算結果に基づいてテーブルへの高速アクセスを得るのに役立ちます。 たとえば、SELECT * FROM people WHERE (first_name | | '| last_name) = 'John Smith'; ステートメントを最適化するには、CREATE INDEX people_names ON people ((first_name | |' | | last_name)); ステートメントを実行して式インデックスを作成します。