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

MaxCompute:ビットマップインデックス (ベータ版)

最終更新日:Jan 20, 2025

ビットマップインデックスは新しいタイプのインデックスです。 重複の頻度が高い列にビットマップインデックスを作成できます。 ビットマップインデックスは、ポイントクエリとレンジクエリの効率を向上させることができます。 このトピックでは、MaxComputeでビットマップインデックスを使用する方法について説明します。

背景情報

MaxComputeには、ハッシュクラスタ化インデックス、範囲クラスタ化インデックス、ブルームフィルタインデックス、ビットマップインデックスの4種類のインデックスが用意されています。 すべてのタイプのインデックスは、ポイントクエリのデータフィルタリングを提供します。 範囲クラスタ化インデックスは、左端のマッチング原理が適用されるシナリオでの範囲フィルタリングに適しています。 ブルームフィルタインデックスは、ポイントクエリに適しています。 ビットマップインデックスは範囲クエリに適しており、範囲フィルタリングシナリオで60% 以上のデータを除外してクエリを高速化できます。

ビットマップインデックスには、次の利点があります。

  • 各ビットマップインデックスに基づくクエリは、独立しており、最も左のマッチング原理に従わない。

  • 複数の列がサポートされています。 テーブル内の1つ以上の列にビットマップインデックスを作成できます。 ビットマップインデックスを他のインデックスとともに使用して、クエリを高速化することもできます。

  • 高いろ过の性能は提供されます。 ビットマップインデックスを使用すると、各値のビットマップを作成できます。 このように、フィルタ結果は、行に対して正確であり得る。 ビットマップインデックスは、重複の頻度が高く、データ集約型のシナリオで高いフィルタリングパフォーマンスを提供します。

  • ビットマップインデックスは、交差演算と和演算 (OR演算とand演算) に適しており、多次元クエリを最適化できます。

シナリオ

  • ビットマップインデックスは、性別列や都市列など、異なる値の数が限られている低濃度列に適しています。

  • ビットマップインデックスは、ANDやORなどの論理演算を実行するのに適しています。 ビットマップインデックスは、ビットマップに対してビット単位の操作を効率的に実行できます。

説明

重複する値の数が過度に多い列や、クエリフィルタの効果が悪いと、多くの記憶リソースが消費され、読み取り性能が低下する可能性がある。 したがって、次の列にはビットマップインデックスを作成しないことをお勧めします。

  • IDカード番号や携帯電話番号を一覧表示する列など、多数の異なる値を持つ列。

  • 頻繁に更新する必要がある列。

課金

  • ストレージ: ビットマップインデックスの作成後、追加のストレージスペースが占有されます。 占有ストレージスペースは、インデックスの実際のストレージサイズに基づいて計算されます。 プロジェクトデータの占有ストレージ容量とストレージサイズは、課金用に統合されます。 価格は標準ストレージの価格と同じです。

  • コンピューティング: ビットマップインデックスの作成により、追加のコンピューティングワークロードがトリガーされます。 これは、コンピューティングリソースの消費を増加させる。 サブスクリプション課金方法が使用されている場合、プロジェクトのサブスクリプションリソースが直接使用されます。 従量課金方法を使用する場合、インデックス関連のコンピューティングジョブのコストは、次の式に基づいて計算されます。従量課金SQLジョブの単価 × 複雑さ1 × インデックス関連のジョブの入力データ量

制限事項

  • ビットマップインデックスは、STRING、CHAR、VARCHAR、TINYINT、SMALLINT、INT、BIGINT、およびDOUBLE型のネストされていない列に対してのみ作成できます。

  • ビットマップインデックスが作成された後、<=<=>>=INBETWEEN、およびIS NULLの論理演算子を含むクエリを高速化できます。

使用上の注意

  • ビットマップインデックスを作成する前に、setproject odps.schema.evolution.enable=true; コマンドを実行してスキーマの進化を有効にする必要があります。

  • ビットマップインデックスは、一度に1つの列に対してのみ作成できます。 テーブルの複数の列にビットマップインデックスを作成する必要がある場合は、ビットマップインデックス作成ステートメントを複数回実行する必要があります。

  • テーブルのビットマップインデックスを作成した後にテーブルにデータを挿入すると、作成されたビットマップインデックスが挿入されたデータに自動的に適用されます。

  • 既存のデータにビットマップインデックスを適用するには、ビットマップインデックスを再構築する必要があります。

サンプルデータ

説明

ビットマップインデックスに関連する構文を使用する例は、empテーブルとsale_detailテーブルのデータに基づいています。

非パーティションテーブル

  1. empという名前のテーブルを作成します。

    CREATE TABLE IF NOT EXISTS emp( 
      empno BIGINT, 
      ename STRING, 
      job STRING, 
      mgr BIGINT, 
      sex STRING 
    );
  2. テーブルにデータを挿入します。

    INSERT INTO emp(empno,ename,job,mgr,sex) VALUES  
    (7369,'smith','clerk',7902,'Male'),
    (7499,'allen','salesman',7698,'Female'),
    (7521,'ward','salesman',7698,'Male'),
    (7654,'martin','salesman',7698,'Male'),
    (7698,'blake','manager',7839,'Male'),
    (7782,'clark','manager',7839,'Male'),
    (7788,'scott','analyst',7566,'Male'),
    (7839,'king','president',NULL,'Male'),
    (7844,'turner','salesman',7698,'Female'),
    (7876,'adams','clerk',7788,'Female'),
    (7900,'james','clerk',7698,'Male'),
    (7902,'ford','analyst',7566,'Male'),
    (7934,'miller','clerk',7782,'Female');

パーティション分割されたテーブル

  1. sale_detailという名前のパーティションテーブルを作成します。

    CREATE TABLE IF NOT EXISTS sale_detail(
     shop_name     STRING,
     customer_id   STRING,
     total_price   DOUBLE)
    PARTITIONED BY (sale_date STRING, region STRING);
  2. パーティションを作成します。

    ALTER TABLE sale_detail ADD PARTITION (sale_date='2023', region='china') PARTITION (sale_date='2024', region='shanghai');

ビットマップインデックスの作成

構文

CREATE BITMAP INDEX <index_name> ON TABLE <table_name> FOR COLUMNS(<col_name>) [COMMENT 'indexcomment'];

Parameters

  • index_name: 必須です。 インデックスの名前。

  • table_name: 必須です。 テーブルの名前。

  • col_name: 必須です。 ビットマップインデックスを作成する列の名前。

  • empテーブルのempno列にempno_indexビットマップインデックスを作成します。

    CREATE BITMAP INDEX empno_index 
    ON TABLE emp 
    FOR COLUMNS(empno) 
    COMMENT 'idxcomment';
  • empテーブルのjob列のjob_indexビットマップインデックスを作成します。

    CREATE BITMAP INDEX job_index 
    ON TABLE emp 
    FOR COLUMNS(job) 
    COMMENT 'idxcomment';
  • sale_detailテーブルのshop_name列のshop_name_indexビットマップインデックスを作成します。

    CREATE BITMAP INDEX shop_name_index  
    ON TABLE sale_detail 
    FOR COLUMNS(shop_name) 
    COMMENT 'indexcomment';

ビットマップインデックスの再構築

構文

次のいずれかのステートメントを実行して、既存のデータのビットマップインデックスを再構築します。

  • パーティション分割されていないテーブルのビットマップインデックスを再構築します。

    ALTER TABLE <table_name> REBUILD BITMAP INDEX;
  • パーティションテーブルのビットマップインデックスを再構築します。

    ALTER TABLE <table_name> PARTITION 
    (<partition_name1=value1>[, partition_name2=value2, ...]) REBUILD BITMAP INDEX;
    説明

    パーティションテーブル内の1つのパーティションのビットマップインデックスを一度に再構築できます。

Parameters

  • パーティション分割されていないテーブル

    table_name: 必須です。 テーブルの名前。

  • パーティションテーブル

    • table_name: 必須です。 テーブルの名前。

    • partition_name: 必須です。 パーティションの名前。

    • value: required パーティションの値。

  • 例1: パーティション分割されていないテーブルのビットマップインデックスを再構築します。

    ALTER TABLE emp REBUILD BITMAP INDEX;
  • 例2: パーティションテーブルのビットマップインデックスを再構築します。

    ALTER TABLE sale_detail PARTITION (sale_date='2023', region='china') REBUILD BITMAP INDEX;

ビットマップインデックスの照会

構文

SHOW INDEXES ON <table_name>;

Parameters

table_name: 必須です。 テーブルの名前。

-- Query indexes of the emp table
SHOW INDEXES ON emp;

次の応答が返されます。

{"Indexes": [{
            "id": "00c84b0e9e6e4097bdfe3a01b91848ac",
            "indexColumns": [{"name": "job"}],
            "name": "job_index",
            "properties": {"comment": "jobidx"},
            "type": "BITMAP"},
           {
            "id": "18a9755c7a8a4182a6b51165e786aa62",
            "indexColumns": [{"name": "empno"}],
            "name": "empno_index",
            "properties": {"comment": "idxcomment"},
            "type": "BITMAP"}]}

データの照会とビットマップインデックスのフィルタリング効果の表示

    • 例1: job列でポイントクエリを実行します。

      SELECT * FROM emp WHERE job = 'clerk';

      次の応答が返されます。

      +------------+-------+-----+------------+------------+-----+
      | empno      | ename | job | mgr        | hiredate   | sex |
      +------------+-------+-----+------------+------------+-----+
      | 7369       | smith | clerk | 7902       | NULL       | Male |
      | 7876       | adams | clerk | 7788       | NULL       | Female |
      | 7900       | james | clerk | 7698       | NULL       | Male |
      | 7934       | miller | clerk | 7782       | NULL       | Female |
      +------------+-------+-----+------------+------------+-----+
    • 例2: empno列で範囲クエリを実行します。

      SELECT * FROM emp WHERE empno BETWEEN 7300 AND 7800;

      次の応答が返されます。

      +------------+------------+------------+------------+------------+
      | empno      | ename      | job        | mgr        | sex        | 
      +------------+------------+------------+------------+------------+
      | 7369       | smith      | clerk      | 7902       | Male       | 
      | 7499       | allen      | salesman   | 7698       | Female     | 
      | 7521       | ward       | salesman   | 7698       | Male       | 
      | 7654       | martin     | salesman   | 7698       | Male       | 
      | 7698       | blake      | manager    | 7839       | Male       | 
      | 7782       | clark      | manager    | 7839       | Male       | 
      | 7788       | scott      | analyst    | 7566       | Male       | 
      +------------+------------+------------+------------+------------+
  1. ビットマップインデックスのフィルタリング効果を照会します。

    1. コンソールに表示される操作ログで、LogView URLをクリックしてLogViewページに移動します。

      image

    2. LogViewページの [Jsonの概要] タブで、ビットマップキーワードを検索し、ビットマップインデックスとビットマップインデックスの作成にかかる追加時間に基づいてフィルタリング結果を表示します。 I/O操作にかかる時間は含まれていません。

      image

ビットマップインデックスの削除

構文

DROP INDEX [IF EXISTS] <index_name> ON TABLE <table_name>;

Parameters

  • index_name: 必須です。 インデックスの名前。

  • table_name: 必須です。 テーブルの名前。

DROP INDEX IF EXISTS job_index ON TABLE emp;