メインコンテンツまでスキップ

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';

上記のステートメントを実行すると、以下の図に示すようにビットマップインデックスが生成されます。

figure
  1. 辞書の作成: StarRocksはGender列に対して辞書を作成し、femalemaleをINT型のコード化された値(01)にマッピングします。
  2. ビットマップの生成: StarRocksはコード化された値に基づいてfemalemaleのビットマップを生成します。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つのステートメントを実行すると、以下の図に示すようにビットマップインデックスが生成されます。

figure

StarRocksはそれぞれGender列とIncome_level列に対して辞書を作成し、これら2つの列の異なる値に対してビットマップを生成します。

  • Gender: femaleのビットマップは1110であり、maleのビットマップは0001です。
  • Producer: level_1のビットマップは1010level_2のビットマップは0100level_3のビットマップは0001です。

level_1の給与をもらっている女性従業員を調べたい場合、次のクエリを送信することができます。

SELECT xxx FROM employee WHERE Gender = female AND Income_level = level_1;

クエリが送信されると、StarRocksはGenderIncome_levelの両方の辞書を同時に検索して以下の情報を取得します:

  • femaleのコード化された値は0であり、ビットマップは1110です。
  • level_1のコード化された値は0であり、ビットマップは1010です。

StarRocksはAND演算子に基づいて1110 & 1010のビットワイズ論理演算を行い、結果として1010を取得します。この結果に基づいて、StarRocksは最初の行と3行目のみを読み取ります。