メインコンテンツまでスキップ
バージョン: 26.x

ソートキーとプレフィックスインデックス

Index Principles

Dorisはデータを SSTable(Sorted String Table)に類似した構造で格納します。この構造は、一つまたは複数の指定された列に従ってソートおよび格納できる順序付きデータ構造です。このようなデータ構造では、ソートされた列の全部または一部における条件検索が非常に効率的です。

Aggregate、Unique、およびDuplicateデータモデルでは、基盤となるデータストレージは、CREATE TABLE文において AGGREGATE KEY、UNIQUE KEY、および DUPLICATE KEY の下で指定された列に従ってソートされます。これらのキーはソートキーと呼ばれます。ソートキーにより、Dorisはクエリ時にソートされた列に条件を指定することで、Table全体をスキャンすることなく必要なデータを素早く特定でき、検索の複雑さを軽減し、クエリを高速化します。

ソートキーに基づいて、Dorisはプレフィックスインデックスを導入しています。プレフィックスインデックスはスパースインデックスです。Table内のデータは、対応する行数に従って論理データブロック(Data Block)を形成します。各論理データブロックは、プレフィックスインデックスTableにインデックスエントリを格納し、インデックスエントリの長さは36バイトを超えません。エントリの内容は、データブロック内の最初の行のソート列で構成されるプレフィックスです。プレフィックスインデックスTableを検索する際、行データが位置する論理データブロックの開始行番号の判定に役立ちます。プレフィックスインデックスは比較的小さいため、メモリに完全にキャッシュでき、データブロックの迅速な特定が可能になり、クエリ効率が大幅に向上します。

ヒント

データブロック内の行の最初の36バイトが、その行のプレフィックスインデックスとして使用されます。VARCHAR型に遭遇した場合、プレフィックスインデックスは直接切り詰められます。最初の列がVARCHARの場合、36バイトに達していなくても直接切り詰められ、後続の列はプレフィックスインデックスに含まれません。

Use Cases

プレフィックスインデックスは等価クエリと範囲クエリを高速化できます。

Managing Indexes

プレフィックスインデックスを定義する特定の構文はありません。Table作成時に、TableのKeyの最初の36バイトが自動的にプレフィックスインデックスとして取得されます。

Recommendations for Prefix Index Selection

ヒント

TableのKey定義は一意であるため、Tableには一組のプレフィックスインデックスのみが存在します。そのため、Table構造を設計する際に適切なプレフィックスインデックスを選択することが重要です。以下の推奨事項を考慮できます:

  1. WHEREフィルタ条件で最も頻繁に使用されるフィールドをKeyとして選択する。
  2. より頻繁に使用されるフィールドを前方に配置する。プレフィックスインデックスは、WHERE条件内のフィールドがKeyのプレフィックスの一部である場合のみ有効であるため。

プレフィックスインデックスでカバーされていない他の列を条件として使用するクエリでは、効率が要件を満たさない場合があります。二つの解決策があります:

  1. 高速化が必要なクエリの列に転置インデックスを作成する。Tableには多数の転置インデックスを持つことができます。
  2. DUPLICATETableでは、列順序を調整した対応する強整合性マテリアライズドビューを作成することで、間接的にマルチプレフィックスインデックスを実現できます。詳細については、クエリ高速化/マテリアライズドビューを参照してください。

Using Indexes

プレフィックスインデックスはWHERE句での等価クエリと範囲クエリの高速化に使用されます。適用可能な場合は自動的に有効になり、特別な構文は必要ありません。

プレフィックスインデックスの高速化効果は、Query Profileの以下のメトリクスを使用して分析できます:

  • RowsKeyRangeFiltered:プレフィックスインデックスによってフィルタされた行数。他のRows値と比較して、インデックスのフィルタ効果を分析できます。

Example Usage

  • Tableのソート列が以下の通りであると仮定すると、プレフィックスインデックスは:user_id(8 Bytes)+ age(4 Bytes)+ message(プレフィックス20 Bytes)となります。
ColumnNameタイプ
user_idBIGINT
ageINT
messageVARCHAR(100)
max_dwell_timeDATETIME
min_dwell_timeDATETIME
  • Tableのソート列が以下の通りであると仮定すると、プレフィックスインデックスはuser_name(20 Bytes)となります。36バイトに達していなくても、VARCHARに遭遇したため直接切り詰められ、後続の列は含まれません。
ColumnNameタイプ
user_nameVARCHAR(20)
ageINT
messageVARCHAR(100)
max_dwell_timeDATETIME
min_dwell_timeDATETIME
  • クエリ条件がプレフィックスインデックスのプレフィックスである場合、クエリを大幅に高速化できます。例えば、最初の例では、以下のクエリを実行します:
SELECT * FROM table WHERE user_id = 1829239 AND age = 20;

このクエリは、以下のクエリよりもはるかに効率的です:

SELECT * FROM table WHERE age = 20;

したがって、Tableを作成する際に正しいカラム順序を選択することで、クエリ効率を大幅に向上させることができます。