インデックス概要
データベースインデックスはクエリを高速化するために使用されます。異なるクエリシナリオを高速化するために、Dorisは様々な豊富なインデックスをサポートしています。
インデックスのタイプと原理
クエリの高速化とその原理の観点から、Dorisのインデックスは主に2つのタイプに分類されます:ポイントクエリインデックスとスキップインデックスです。
- ポイントクエリインデックス: 主にポイントクエリの高速化に使用され、その原理はインデックスを通じてWHERE条件を満たす行を特定し、その行を直接読み取ることです。ポイントクエリインデックスは条件を満たす行数が少ない場合に非常に効果的です。DorisのポイントクエリインデックスにはPrefix IndexとInverted Indexが含まれます。
- Prefix Index: Dorisはソートキーに従って順序立ててデータを保存し、1024行ごとに疎なプレフィックスインデックスを作成します。インデックス内のキーは、現在の1024行の最初の行における並び替え列の値です。クエリが並び替え列を含む場合、システムは関連する1024行グループの最初の行を見つけ、そこからスキャンを開始します。
- Inverted Index: 転置インデックスを持つ列に対して、各値をrow idのセットにマッピングするposting listが作成されます。等値クエリの場合、最初にposting listからrow idのセットを見つけ、次にそれらの行のデータを直接読み取り、行ごとのスキャンを回避します。転置インデックスは範囲フィルタリングと全文検索も高速化できます。アルゴリズムはより複雑ですが、基本的な原理は同様です。(注:以前のBITMAPインデックスは、より強力な転置インデックスに置き換えられました。)
- スキップインデックス: 主に分析の高速化に使用され、その原理はインデックスを通じてWHERE条件を満たさないデータブロックを判定し、これらのブロックをスキップして、条件を満たす可能性のあるデータブロックのみを読み取り、その後行ごとのフィルタを実行して最終的に条件を満たす行を取得することです。スキップインデックスは条件を満たす行数が多い場合により効果的です。DorisのスキップインデックスにはZoneMapインデックス、BloomFilterインデックス、NGram BloomFilterインデックスが含まれます。
- ZoneMap Index: 各列の統計を自動的に維持し、各データファイル(Segment)およびデータブロック(Page)の最大値、最小値、NULL値の有無を記録します。等値クエリ、範囲クエリ、IS NULLの場合、最大値、最小値、NULL値の有無に基づいて、データファイルとデータブロックが条件を満たすデータを含むことができるかどうかを判定できます。含まない場合、Dorisは対応するファイルやデータブロックの読み取りをスキップし、IOを削減してクエリを高速化します。
- BloomFilter Index: インデックス対象列の値をBloomFilterデータ構造に保存し、非常に少ないストレージ容量で値がBloomFilter内にあるかどうかを素早く判定できます。等値クエリの場合、値がBloomFilter内にない場合、対応するデータファイルやデータブロックをスキップでき、IOを削減してクエリを高速化します。
- NGram BloomFilter Index: テキストのLIKEクエリの高速化に使用されます。原理はBloomFilterインデックスと類似していますが、元のテキスト値を保存する代わりに、テキストのNGramトークン化を実行し、各トークンをBloomFilterに保存します。LIKEクエリの場合、LIKEパターンもNGramを使用してトークン化されます。いずれかのトークンがBloomFilter内にない場合、対応するデータファイルやデータブロックはLIKE条件を満たさないためスキップできます。
上記のインデックスのうち、プレフィックスインデックスとZoneMapインデックスはDorisが自動的に維持する組み込みインデックスであり、ユーザー管理は不要です。転置インデックス、BloomFilterインデックス、NGram BloomFilterインデックスは、シナリオに基づいてユーザーが手動で作成・管理する必要があります。
- 異なるタイプのインデックスの特性比較
| タイプ | インデックス | 利点 | 制限 |
|---|---|---|---|
| ポイントクエリ | Prefix Index | 組み込みインデックス、最高のパフォーマンス。 Tableあたり1つのプレフィックスインデックスのみ。 | Tableあたり1つのプレフィックスインデックスのみ。 |
| ポイントクエリ | Inverted Index | トークン化とキーワードマッチングをサポート。 任意の列でのインデックス構築。 マルチ条件組み合わせとより多くの機能の高速化。 | インデックスストレージ容量が大きく、生データと同程度。 |
| スキップ | ZoneMap Index | 組み込みインデックス、インデックスストレージ容量が小さい。 Tableあたり1つのプレフィックスインデックスのみ。 | Tableあたり1つのプレフィックスインデックスのみ。 |
| スキップ | BloomFilter Index | ZoneMapより正確、インデックス容量は中程度。 | サポートするクエリタイプが少ない。 等値のみサポート(その他:不等値、範囲、LIKE、MATCHはサポートしない)。 |
| スキップ | NGram BloomFilter | LIKE高速化をサポート、インデックス容量は中程度。 | サポートするクエリタイプが少ない。 LIKE高速化のみサポート。 |
- インデックス高速化のオペレータと関数のリスト
| オペレータまたは関数 | Prefix Index | Inverted Index | ZoneMap Index | BloomFilter Index | NGram BloomFilter Index |
|---|---|---|---|---|---|
| = | YES | YES | YES | YES | NO |
| != | YES | YES | NO | NO | NO |
| IN | YES | YES | YES | YES | NO |
| NOT IN | YES | YES | NO | NO | NO |
| >, >=, <, <=, BETWEEN | YES | YES | YES | NO | NO |
| IS NULL | YES | YES | YES | NO | NO |
| IS NOT NULL | YES | YES | NO | NO | NO |
| LIKE | NO | NO | NO | NO | YES |
| MATCH, MATCH_* | NO | YES | NO | NO | NO |
| array_contains | NO | YES | NO | NO | NO |
| array_overlaps | NO | YES | NO | NO | NO |
| is_ip_address_in_range | NO | YES | NO | NO | NO |
インデックス設計ガイドライン
データベースTableインデックスの設計と最適化は、データ分散とクエリに密接に関連しており、実際のシナリオに基づいたテストと最適化が必要です。「銀の弾丸」は存在しませんが、Dorisはインデックスの使用難易度を継続的に下げることに努めています。ユーザーはインデックスの選択とテストについて、これらのシンプルなガイドラインに従うことができます。
- 最も頻繁に使用されるフィルタ条件をKEYとして指定し、プレフィックスインデックスを自動作成します。これは最高のフィルタ効果を持ちます。ただし、Tableあたり1つのプレフィックスインデックスのみ作成できるため、最も頻繁なフィルタ条件に使用すべきです。
- フィルタ高速化が必要な非キーフィールドについては、幅広い適用性とマルチ条件組み合わせにより、最初の選択肢は転置インデックスの作成です。2番目の選択肢には以下の2つのインデックスが含まれます:
- 文字列のLIKEマッチングが必要な場合は、NGram BloomFilterインデックスを追加します。
- インデックスストレージ容量が重要な場合は、転置インデックスをBloomFilterインデックスに置き換えます。
- パフォーマンスが期待通りでない場合は、QueryProfileを通じてインデックスによってフィルタされるデータ量と消費時間を分析します。詳細については各インデックスの詳細ドキュメントを参照してください。