ビットマップインデックス
このトピックでは、ビットマップインデックスの作成と管理方法、および使用例について説明します。
はじめに
ビットマップインデックスは、ビットマップ(ビットの配列)を使用する特別なデータベースインデックスです。ビットは常に2つの値のいずれか(0または1)を持ちます。ビットマップの各ビットはテーブル内の1行に対応し、各ビットの値は対応する行の値に依存します。
ビットマップインデックスは、特定の列のクエリパフォーマンスを向上させるのに役立ちます。クエリのフィルタ条件がプレフィックスインデックスに一致する場合、クエリ効率を大幅に向上させ、迅速に結果を返すことができます。ただし、テーブルには1つのプレフィックスインデックスしか持てません。クエリのフィルタ条件がプレフィックスインデックスのプレフィックスを含まない場合、その列にビットマップインデックスを作成してクエリ効率を向上させることができます。
クエリを高速化するためのビットマップインデックスの設計方法
ビットマップインデックスを選択する際の主な考慮事項は、列の基数とクエリに対するビットマップインデックスのフィルタリング効果です。一般的な誤解とは異なり、StarRocksのビットマップインデック スは、高基数の列に対するクエリや、複数の低基数列の組み合わせに対するクエリにより適しています。さらに、ビットマップインデックスはデータを効果的にフィルタリングし、少なくとも999/1000のデータをフィルタリングすることで、読み込むページデータの量を減らすことができます。
単一の低基数列に対するクエリでは、ビットマップインデックスのフィルタリング効果は低く、多くの行を読み込む必要があり、複数のページに分散されているためです。
ビットマップインデックスがクエリに与えるフィルタリング効果を評価する際には、データロードのコストを考慮する必要があります。StarRocksでは、基礎データはページ(デフォルトサイズは64K)で整理され、ロードされます。データロードのコストには、ディスクからページをロードする時間、ページを解凍する時間、デコードする時間が含まれます。
ただし、過度に高い基数は、より多くのディスクスペースを占有するなどの問題を引き起こす可能性があります。また、ビットマップインデックスはデータロード中に構築される必要があるため、頻繁なデータロードはロードパフォーマンスに影響を与える可能性があります。
さらに、クエリ中のビットマップインデックスのロードオーバーヘッドも考慮する必要があります。クエリ中にビットマップインデックスはオンデマンドでロードされ、クエリ条件に関与する列の値の数/基数 x ビットマップインデックス
の値が大きいほど、クエリ中のビットマップインデックスのロードオーバーヘッドが大きくなります。
ビットマップインデックスの適切な基数とクエリ条件を決定するために、このトピックのビットマップインデックスのパフォーマンステストを参照してパフォーマンステストを実施することをお勧めします。実際のビジネスデータとクエリを使用して、異なる基数の列にビットマップインデックスを作成し、クエリに対するビットマップインデックスのフィルタリング効果(少なくとも999/1000のデータをフィルタリング)、ディスクスペースの使用量、ロードパフォーマンスへの影響、クエリ中のビットマップインデックスのロードオーバーヘッドを分析することができます。
StarRocksには、ビットマップインデックスの適応選択メカニズムが組み込まれています。ビットマップインデックスがクエリを高速化できない場合、例えば、多くのページをフィルタリングできない場合や、クエリ中のビットマップインデックスのロードオーバーヘッドが高い場合、クエリ中に使用されないため、クエリパフォーマンスに大きな影響を与えることはありません。
ビットマップインデックスの適応選択
StarRocksは、列の基数とクエリ条件に基づいてビットマップインデックスを使用するかどうかを適応的に選択できます。ビットマップインデックスが多くのページを効果的にフィルタリングできない場合や、クエリ中のビットマップインデックスのロードオーバーヘッドが高い場合、StarRocksはデフォルトでビットマップインデックスを使用しないため、クエリパフォーマンスの低下を避けます。
StarRocksは、クエリ条件に関与する値の数と列の基数の比率に基づいてビットマップインデックスを使用するかどうかを判断します。一般に、この比率が小さいほど、ビットマップインデックスのフィルタリング効果が良好です。したがって、StarRocksはbitmap_max_filter_ratio/1000
をしきい値として使用します。フィルタ条件の値の数/列の基数
がbitmap_max_filter_ratio/1000
より小さい場合、ビットマップインデックスが使用されます。bitmap_max_filter_ratio
のデフォルト値は1
です。
単一の列に基づくクエリの例として、SELECT * FROM employees WHERE gender = 'male';
を考えてみましょう。employees
テーブルのgender
列には、'male'と'female'の値があるため、基数は2(2つの異なる値)です。クエリ条件には1つの値が含まれているため、比率は1/2であり、1/1000より大きいです。したがって、このクエリではビットマップインデックスは使用されません。
複数の列の組み合わせに基づくクエリの例として、SELECT * FROM employees WHERE gender = 'male' AND city IN ('Beijing', 'Shanghai');
を考えてみましょう。city
列の基数は10,000であり、クエリ条件には2つの値が含まれているため、比率は(1*2)/(2*10000)
であり、1/1000より小さいです。したがって、このクエリではビットマップインデックスが使用されます。
bitmap_max_filter_ratio
の値の範囲は1-1000です。bitmap_max_filter_ratio
が1000
に設定されている場合、ビットマップインデックスを持つ列に対するクエリは強制的にビットマップインデックスを使用します。
利点
- ビットマップインデックスは、クエリされた列の値の行番号を迅速に特定でき、ポイントクエリや小範囲のクエリに適しています。
- ビットマップインデックスは、ユニオンやインターセクション操作(ORおよびAND操作)を含む多次元クエリを最適化できます。