このトピックでは、Hologres でビットマップインデックスを使用する方法について説明します。
概要
Hologres では、bitmap_columns
プロパティでビットマップインデックスを指定します。このプロパティは、データストレージとは独立したインデックススキーマを使用します。 bitmap_columns プロパティを使用すると、ビットマップベクトル構造に基づいて等価比較を高速化できます。ビットマップインデックスは、保存ファイル内の指定された値と等しいデータをフィルタリングするのに役立ちます。したがって、bitmap_columns プロパティはポイントクエリに適用できます。ビットマップインデックスを設定するには、次の構文を使用します。
-- Hologres V2.1 以降でサポートされている構文
CREATE TABLE <table_name> (...) WITH (bitmap_columns = '[<columnName>{:[on|off]}[,...]]');
-- すべての Hologres バージョンでサポートされている構文
CREATE TABLE <table_name> (...);
CALL set_table_property('<table_name>', 'bitmap_columns', '[<columnName>{:[on|off]}[,...]]');
パラメーター | 説明 |
table_name | テーブルの名前。 |
columnName | 列の名前。 |
on | 現在の列にビットマップインデックスが作成されることを示します。 |
off | 現在の列にビットマップインデックスが作成されないことを示します。 |
使用上の注意
等価クエリ列にビットマップインデックスを指定することをお勧めします。これにより、Hologres はフィルタ条件を満たすデータが存在する行の番号をすばやく見つけることができます。カーディナリティの高い列にビットマップインデックスを指定すると、追加のストレージオーバーヘッドが発生します。カーディナリティの高い列は、列に重複データが少ないことを示します。
テーブルの各列にビットマップインデックスを指定することはお勧めしません。これは、テーブルの各列にビットマップインデックスを指定すると、追加のストレージオーバーヘッドが発生し、書き込みパフォーマンスに影響を与えるためです。
JSON 形式のデータが TEXT データ型として格納されている列には、ビットマップインデックスを作成しないことをお勧めします。
制限事項
ビットマップインデックスをサポートしているのは、列指向テーブルと行と列のハイブリッドテーブルのみです。行指向テーブルはビットマップインデックスをサポートしていません。
bitmap_columns プロパティで指定された列は null 許容です。
デフォルトでは、列指向テーブルの TEXT データ型のすべての列がビットマップインデックス列として指定されます。
トランザクションブロックの外部で、ビットマップインデックス列を変更するためのステートメントを実行できます。変更された列はすぐに有効になりません。ビットマップインデックスはバックエンドで非同期的に構築および削除されます。詳細については、「ALTER TABLE」をご参照ください。
Hologres V2.0 以降では、
bitmap_columns
をon
またはoff
にのみ設定できます。auto
という値は、bitmap_columns
では無効です。
仕組み
ビットマップインデックスは分散キーやクラスタリングキーとは異なり、データストレージとは独立しています。列にビットマップインデックスを指定すると、Hologres は列の値のバイナリ文字列を生成します。バイナリ文字列は、ビットマップインデックス列の値に対応します。クエリがビットマップインデックスにヒットすると、Hologres はデータが存在する行の番号をすばやく見つけます。ただし、ビットマップインデックスは依然としてオーバーヘッドが発生します。次の項目に注意してください。
テーブルにカーディナリティの高い列が存在する場合、列にビットマップインデックスを指定すると、Hologres は列の値のバイナリ文字列を生成します。多くの個別値が関係する場合、スパース配列が生成され、大量のストレージリソースが消費されます。
ワイドテーブルの各列にビットマップインデックスを指定すると、データの書き込み時に、Hologres はテーブルの列の各値のバイナリ文字列を生成します。これはシステムオーバーヘッドを引き起こし、書き込みパフォーマンスに影響を与えます。
要約すると、ビットマップインデックスを使用すると、ストレージを犠牲にしてデータクエリ時間を短縮できます。ビットマップインデックスは、データが均等に分散されている列に費用対効果があります。
次の例は、EXPLAIN
ステートメントを使用して、クエリがビットマップインデックスにヒットするかどうかを確認する方法を示しています。実行プランに Bitmap Filter
演算子が含まれている場合、クエリはビットマップインデックスにヒットします。
Hologres V2.1 以降でサポートされている構文:
CREATE TABLE bitmap_test ( uid int NOT NULL, name text NOT NULL, gender text NOT NULL, class text NOT NULL, PRIMARY KEY (uid) ) WITH ( bitmap_columns = 'gender,class' ); INSERT INTO bitmap_test VALUES (1,'Bob','Male','Class 1'), (2,'Eric','Male','Class 3'), (3,'Ada','Female','Class 2'), (4,'Joyce','Female','Class 2'), (5,'Leo','Male','Class 2'), (6,'Steve','Male','Class 3'), (7,'Dora','Female','Class 1'); explain SELECT * FROM bitmap_test where gender='Male' AND class='Class 1';
すべての Hologres バージョンでサポートされている構文:
begin; create table bitmap_test ( uid int not null, name text not null, gender text not null, class text not null, PRIMARY KEY (uid) ); call set_table_property('bitmap_test', 'bitmap_columns', 'gender,class'); commit; INSERT INTO bitmap_test VALUES (1,'Bob','Male','Class 1'), (2,'Eric','Male','Class 3'), (3,'Ada','Female','Class 2'), (4,'Joyce','Female','Class 2'), (5,'Leo','Male','Class 2'), (6,'Steve','Male','Class 3'), (7,'Dora','Female','Class 1'); explain SELECT * FROM bitmap_test where gender='Male' AND class='Class 1';
実行プランに Bitmap Filter
演算子が含まれていることを示しています。これは、クエリがビットマップインデックスにヒットしたことを示します。
ビットマップインデックスとクラスタリングキーの違い
類似点:
ビットマップインデックスとクラスタリングキーは、ファイル内のデータをフィルタリングするために使用されます。
相違点:
ビットマップインデックスは、ファイル番号を使用してデータを見つけるために使用されます。したがって、ビットマップインデックスは等価クエリにより適しています。クラスタリングキーは、ファイル内のデータをソートするために使用されます。したがって、クラスタリングキーは範囲クエリにより適しています。
ビットマップインデックスと比較して、クラスタリングキーの優先順位が高くなっています。同じ列にクラスタリングキーとビットマップインデックスを指定すると、クエリオプティマイザは優先的にクラスタリングキーを使用してファイルと照合します。次のステートメントは例を示しています。
Hologres V2.1 以降でサポートされている構文:
-- uid、class、および date 列をクラスタリングキーとして指定し、text 列をビットマップインデックスとして指定します。 CREATE TABLE ck_bit_test ( uid int NOT NULL, name text NOT NULL, class text NOT NULL, date text NOT NULL, PRIMARY KEY (uid) ) WITH ( clustering_key = 'uid,class,date', bitmap_columns = 'name,class,date' ); INSERT INTO ck_bit_test VALUES (1,'Bob','1','2022-10-19'), (2,'Eric,'3','2022-10-19'), (3,'Ada','2','2022-10-20'), (4,'Joyce','2','2022-10-20'), (5,'Leo,'2','2022-10-18'), (6,'Steve','3','2022-10-17'), (7,'Dora','3','2022-10-20');
すべての Hologres バージョンでサポートされている構文:
-- -- uid、class、および date 列をクラスタリングキーとして指定し、text 列をビットマップインデックスとして指定します。 begin; create table ck_bit_test ( uid int not null, name text not null, class text not null, date text not null, PRIMARY KEY (uid) ); call set_table_property('ck_bit_test', 'clustering_key', 'uid,class,date'); call set_table_property('ck_bit_test', 'bitmap_columns', 'name,class,date'); commit; INSERT INTO ck_bit_test VALUES (1,'Bob','1','2022-10-19'), (2,'Eric,'3','2022-10-19'), (3,'Ada','2','2022-10-20'), (4,'Joyce','2','2022-10-20'), (5,'Leo,'2','2022-10-18'), (6,'Steve','3','2022-10-17'), (7,'Dora','3','2022-10-20');
uid、class、および date
列をクエリする場合、SQL クエリステートメントは左端一致原則に準拠し、クエリはクラスタリングキーにヒットします。等価クエリでも、ビットマップインデックスではなくクラスタリングキーが使用されます。SELECT * FROM clustering_test WHERE uid = '3' AND class ='2' AND date > '2022-10-17';
次の図は、実行プランに
Bitmap Filter
演算子ではなくCluster Filter
演算子が含まれていることを示しています。これは、クエリでビットマップインデックスではなくクラスタリングキーが使用されていることを示します。uid、class、および date
列をクエリし、class
列のクエリが範囲クエリである場合、SQL ステートメントで指定された範囲のデータが一致した後、クエリ中に左端一致原則は機能しません。この場合、date
列のクエリは、クエリステートメントが左端一致原則に従っていないため、クラスタリングキーにヒットできません。date
列にビットマップインデックスを指定すると、クエリでビットマップインデックスが使用されます。SELECT * FROM clustering_test WHERE uid = '3' AND class >'2' AND date = '2022-10-17';
次の図は、実行プランに
Cluster Filter
演算子とBitmap Filter
演算子の両方が含まれていることを示しています。これは、uid および class
列のクエリでクラスタリングキーが使用され、date
列のクエリでビットマップインデックスが使用されていることを示します。
例
Hologres V2.1 以降でサポートされている構文:
CREATE TABLE tbl ( a text NOT NULL, b text NOT NULL ) WITH ( bitmap_columns = 'a:on,b:off' ); -- bitmap_columns プロパティを変更します。 ALTER TABLE tbl SET (bitmap_columns = 'a:off');-- ALTER TABLE ステートメントは、すべての列に対してのみ bitmap_columns プロパティの変更をサポートしています。
すべての Hologres バージョンでサポートされている構文:
// tbl という名前のテーブルを作成し、ビットマップインデックスを設定します。 begin; create table tbl ( a text not null, b text not null ); call set_table_property('tbl', 'bitmap_columns', 'a:on,b:off'); commit; -- ビットマップインデックスを変更します。 call set_table_property('tbl', 'bitmap_columns', 'a:off');-- すべての列の bitmap_columns プロパティを変更します。列 a に指定されたビットマップインデックスを削除します。 call update_table_property('tbl', 'bitmap_columns', 'b:off');-- 列 b の bitmap_columns プロパティを変更します。列 b に指定されたビットマップインデックスを削除し、列 a に指定されたビットマップインデックスを保持します。
関連情報
Hologres 内部テーブルの DDL ステートメントの詳細については、以下のトピックを参照してください。