Bitmap indexing
ビットマップインデックス
このトピックでは、ビットマップインデックスの作成と管理方法について説明します。
ビットマップインデックスは、ビットの配列であるビットマップを使用する特殊なデータベースインデックスです。ビットは常に0または1のいずれかの値です。ビットマップの各ビットは、テーブル内の単一の行に対応しています。各ビットの値は、対応する行の値に依存します。
ビットマップインデックスは、指定された列のクエリパフォーマンスを向上させるのに役立ちます。もしクエリがソートキーカラムにヒットした場合、StarRocksはプレフィックスインデックスを使用してクエリ結果を効率的に返します。しかし、データブロックのプレフィック スインデックスエントリは最大36バイトの長さを超えることはできません。もしソートキーとして使用されていない列のクエリパフォーマンスを向上させたい場合は、その列に対してビットマップインデックスを作成することができます。
メリット
ビットマップインデックスは以下の点で利点をもたらします:
- 列のカーディナリティが低い場合(ENUM型の列など)、応答時間を短縮することができます。列の値の数が比較的多い場合は、クエリのスピードを向上させるためにブルームフィルタインデックスを使用することをおすすめします。詳細については、ブルームフィルタインデックスを参照してください。
- 他のインデックステクニックと比較して、ストレージスペースを少なく使用します。ビットマップインデックスは、通常、テーブル内のインデックス化されたデータのサイズの一部しか占めません。
- 複数のビットマップインデックスを組み合わせて複数の列にクエリを発行することができます。詳細については、複数列のクエリを参照してください。
使用上の注意
- 等号(
=
)や[NOT] IN演算子を使用してフィルタリングできる列に対してビットマップインデックスを作成することができます。 - 重複キーのテーブルまたはユニークキーのテーブルのすべての列に対してビットマップインデックスを作成することができます。集約テーブルまたはプライマリキーテーブルの場合、キーカラムに対してのみビットマップインデックスを作成することができます。
- FLOAT、DOUBLE、BOOLEAN、およびDECIMAL型の列はビットマップインデックスの作成をサポートしていません。
- クエリがビットマップインデックスを使用しているかどうかを知るためには、クエリのプロファイルの
BitmapIndexFilterRows
フィールドを表示することができます。
ビットマップインデックスの作成
列に対してビットマップインデックスを作成する方法は2つあります。
-
テーブルの作成時に列に対してビットマップインデックスを作成します。例:
CREATE TABLE d0.table_hash
(
k1 TINYINT,
k2 DECIMAL(10, 2) DEFAULT "10.5",
v1 CHAR(10) REPLACE,
v2 INT SUM,
INDEX index_name (column_name [, ...]) [USING BITMAP] [COMMENT '']
)
ENGINE = olap
AGGREGATE KEY(k1, k2)
DISTRIBUTED BY HASH(k1)
PROPERTIES ("storage_type" = "column");次の表は、ビットマップインデックスに関連するパラメータを説明しています。
パラメータ
必須
説明
index_name
Yes
ビットマップインデックスの名前です。命名規則は次のとおりです:
- 名前には英数字(0-9)とアンダースコア(_)を含めることができます。ただし、英字で始める必要があります。
- 名前の長さは64文字を超えることはできません。
ビットマップインデックスの名前はテーブル内で一意である必要があります。
column_name
Yes
ビットマップインデックスを作成する列の名前です。複数の列名を指定して一度に複数の列にビットマップインデックスを作成することができます。複数の列をカンマ(
,
)で区切って指定します。COMMENT
No
ビットマップインデックスのコメントです。
INDEX index_name (column_name [, ...]) [USING BITMAP] [COMMENT '']
コマンドをカンマ(,
)で区切って指定することで、複数の列に対して一度にビットマップインデックスを作成することができます。他のCREATE TABLEステートメントのパラメータの説明については、CREATE TABLEを参照してください。 -
CREATE INDEXステートメントを使用してテーブルの列にビットマップインデックスを作成します。パラメータの説明と例については、CREATE INDEXを参照してください。
CREATE INDEX index_name ON table_name (column_name) [USING BITMAP] [COMMENT ''];
ビットマップインデックスの表示
SHOW INDEXステートメントを使用して、テーブルに作成されたすべてのビットマップインデックスを表示することができます。パラメータの説明と例については、SHOW INDEXを参照してくだ さい。
SHOW { INDEX[ES] | KEY[S] } FROM [db_name.]table_name [FROM db_name];
注意
インデックスの作成は非同期プロセスです。そのため、作成プロセスが完了したインデックスのみ表示されます。
ビットマップインデックスの削除
DROP INDEXステートメントを使用して、テーブルからビットマップインデックスを削除することができます。パラメータの説明と例については、DROP INDEXを参照してください。
DROP INDEX index_name ON [db_name.]table_name;
使用例
例えば、以下のemployee
テーブルは会社の従業員情報の一部を示しています。
ID | Gender | Position | Income_level |
---|---|---|---|
01 | 女 | 開発者 | レベル1 |
02 | 女 | アナリスト | レベル2 |
03 | 女 | セールスマン | レベル1 |
04 | 男 | 会計士 | レベル3 |
単一列のクエリ
例えば、Gender
列のクエリパフォーマンスを向上させたい場合、以下のステートメントを使用して列にビットマップインデックスを作成することができます。
CREATE INDEX index1 ON employee (Gender) USING BITMAP COMMENT 'index1';
上記のステートメントを 実行すると、以下の図に示すようにビットマップインデックスが生成されます。
- 辞書の作成: StarRocksは
Gender
列に対して辞書を作成し、female
とmale
をINT型のコード化された値(0
と1
)にマッピングします。 - ビットマップの生成: StarRocksはコード化された値に基づいて
female
とmale
のビットマップを生成します。female
のビットマップは1110
であり、female
は最初の3行に表示されるためです。male
のビットマップは0001
であり、male
は4行目にのみ表示されるためです。
会社の男性従業員を調べたい場合、次のクエリを送信することができます。
SELECT xxx FROM employee WHERE Gender = male;
クエリが送信されると、StarRocksは辞書を検索してmale
のコード化された値を取得し、ビットマップインデックスからmale
のビットマップを取得します。この場合、ビットマップは0001
です。これは、4行目のみがクエリ条件に一致することを意味します。その後、StarRocksは最初の3行をスキップして、4行目のみを読み取ります。
複数列のクエリ
例えば、Gender
列とIncome_level
列のクエリパフォーマンスを向上させたい場合、以下のステートメントを使用してこれらの2つの列に対してビットマップインデックスを作成することができます。
-
Gender
CREATE INDEX index1 ON employee (Gender) USING BITMAP COMMENT 'index1';
-
Income_level
CREATE INDEX index2 ON employee (Income_level) USING BITMAP COMMENT 'index2';
上記の2つのステートメントを実行すると、以下の図に示すようにビットマップインデックスが生成されます。
StarRocksはそれぞれGender
列とIncome_level
列に対して辞書を作成し、これら2つの列の異なる値に対してビットマップを生成します。
Gender
:female
のビットマップは1110
であり、male
のビットマップは0001
です。Producer
:level_1
のビットマップは1010
、level_2
のビットマップは0100
、level_3
のビットマップは0001
です。
level_1
の給与をもらっている女性従業員を調べたい場合、次のクエリを送信することができます。
SELECT xxx FROM employee WHERE Gender = female AND Income_level = level_1;
クエリが送信されると、StarRocksはGender
とIncome_level
の両方の辞書を同時に検索して以下の情報を取得します:
female
のコード化された値は0
であり、ビットマップは1110
です。level_1
のコード化された値は0
であり、ビットマップは1010
です。
StarRocksはAND
演算子に基づいて1110 & 1010
のビットワイズ論理演算を行い、結果として1010
を取得します。この結果に基づいて、StarRocksは最初の行と3行目のみを読み取ります。