Topik ini menjelaskan cara menggunakan indeks bitmap di Hologres.
Ikhtisar
Di Hologres, properti bitmap_columns menentukan indeks bitmap. Indeks bitmap adalah struktur indeks independen yang terpisah dari penyimpanan data dan dirancang untuk mempercepat kueri kesetaraan (equality queries). Indeks ini menggunakan vektor bitmap untuk menyaring data secara cepat dalam blok file, sehingga cocok untuk skenario penyaringan berdasarkan kesetaraan. Gunakan sintaks berikut:
-- Sintaks yang didukung oleh Hologres V2.1 dan versi lebih baru
CREATE TABLE <table_name> (...) WITH (bitmap_columns = '[<columnName>{:[on|off]}[,...]]');
-- Sintaks yang didukung oleh semua versi
CREATE TABLE <table_name> (...);
CALL set_table_property('<table_name>', 'bitmap_columns', '[<columnName>{:[on|off]}[,...]]');
|
Parameter |
Deskripsi |
|
table_name |
Nama tabel. |
|
columnName |
Nama kolom. |
|
on |
Mengaktifkan indeks bitmap untuk kolom yang ditentukan. |
|
off |
Menonaktifkan indeks bitmap untuk kolom yang ditentukan. |
Rekomendasi
-
Buat indeks bitmap pada kolom yang sering digunakan dalam kueri kesetaraan agar sistem dapat dengan cepat menemukan nomor baris data yang sesuai. Namun, penggunaan indeks bitmap pada kolom dengan kardinalitas tinggi (kolom yang memiliki sedikit nilai duplikat) dapat menyebabkan overhead penyimpanan yang signifikan.
-
Hindari membuat indeks bitmap pada setiap kolom karena praktik ini tidak hanya menimbulkan overhead penyimpanan tambahan, tetapi juga mengurangi throughput penulisan—Hologres harus membangun indeks untuk setiap kolom selama ingesti data.
-
Jangan membuat indeks bitmap pada kolom teks yang menyimpan data berformat JSON.
Batasan
-
Indeks bitmap didukung pada tabel berorientasi kolom dan tabel hibrida baris-kolom, tetapi tidak didukung pada tabel berorientasi baris.
-
Kolom yang memiliki indeks bitmap dapat berisi nilai null.
-
Secara default, indeks bitmap dibuat secara implisit pada semua kolom bertipe data text.
-
Anda dapat menjalankan perintah untuk mengatur indeks bitmap di luar transaksi. Perubahan tersebut tidak langsung berlaku karena Hologres melakukan pembuatan dan penghapusan encoding bitmap secara asinkron di latar belakang. Untuk informasi lebih lanjut, lihat ALTER TABLE.
-
Properti
bitmap_columnshanya mendukungonatauoff. Mulai Hologres V2.0, pengaturan propertibitmap_columnskeautotidak lagi didukung.
Cara kerja
Berbeda dengan kunci distribusi (distribution key) atau kunci pengelompokan (clustering key), indeks bitmap adalah struktur indeks independen yang terpisah dari penyimpanan data. Saat kueri menggunakan indeks ini, sistem dapat dengan cepat menemukan nomor baris untuk menyaring data. Namun, indeks bitmap memiliki overhead. Pertimbangkan skenario berikut:
-
Kolom dengan kardinalitas tinggi: Hologres menghasilkan bitmap untuk setiap nilai unik. Jika terdapat banyak nilai yang tidak berulang, proses ini membentuk array jarang (sparse array) yang mengonsumsi ruang penyimpanan besar.
-
Semua kolom pada tabel lebar memiliki indeks bitmap: Jika Anda membuat indeks bitmap untuk setiap kolom dalam tabel lebar, Hologres harus membangun bitmap untuk setiap nilai selama ingesti data, yang menciptakan overhead sistem dan mengurangi throughput penulisan.
Secara ringkas, indeks bitmap merupakan pertukaran antara ruang dan waktu. Indeks ini paling efektif secara biaya untuk kolom dengan distribusi data yang relatif merata.
Seperti yang ditunjukkan pada contoh berikut, Anda dapat menggunakan explain SQL untuk memeriksa apakah kueri menggunakan indeks bitmap. Jika rencana eksekusi berisi Bitmap Filter, berarti kueri tersebut menggunakan indeks tersebut.
-
Sintaks yang didukung oleh Hologres V2.1 dan versi lebih baru:
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'; -
Sintaks yang didukung oleh semua versi:
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';
Kehadiran operator Bitmap Filter dalam rencana eksekusi, seperti Bitmap Filter: (gender = 'Male'::text) AND (class = 'Class 1'::text), mengonfirmasi bahwa kueri menggunakan indeks bitmap.
Indeks bitmap vs. kunci pengelompokan
-
Baik indeks bitmap maupun kunci pengelompokan menyaring data dalam file.
-
Indeks bitmap ideal untuk kueri kesetaraan karena menemukan data berdasarkan nomor baris. Sebaliknya, kunci pengelompokan mengurutkan data dalam file, sehingga lebih cocok untuk kueri rentang (range queries).
Kunci pengelompokan memiliki prioritas lebih tinggi daripada indeks bitmap. Jika keduanya dibuat pada kolom yang sama, pengoptimal (optimizer) akan lebih memilih menggunakan kunci pengelompokan. Contoh berikut menunjukkan rinciannya:
-
Sintaks yang didukung oleh Hologres V2.1 dan versi lebih baru:
-- Kolom uid, class, dan date diatur sebagai kunci pengelompokan. -- Secara default, kolom teks seperti name, class, dan date memiliki indeks bitmap. 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'); -
Sintaks yang didukung oleh semua versi:
-- Kolom uid, class, dan date diatur sebagai kunci pengelompokan. -- Secara default, kolom teks seperti name, class, dan date memiliki indeks bitmap. 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');
-
Kueri kesetaraan ini menargetkan kolom
uid,class,date. Karena mengikuti prinsip pencocokan paling kiri (leftmost matching principle), pengoptimal menggunakan kunci pengelompokan alih-alih indeks bitmap.SELECT * FROM ck_bit_test WHERE uid = '3' AND class ='2' AND date > '2022-10-17';Rencana eksekusi berisi operator
Cluster Filtertetapi tidak berisi operatorBitmap Filter, yang menunjukkan bahwa kueri menggunakan kunci pengelompokan. Rencana tersebut menampilkanIndex Scan using holo_index:[1] on ck_bit_testdan filter menggunakanCluster Filter: ((uid = 3) AND (class = '2'::text) AND (date > '2022-10-17'::text)), yang mengonfirmasi penggunaan kunci pengelompokan. -
Kueri dilakukan pada kolom
uid,class,date. Namun, kolomclassdigunakan dalam kueri rentang. Menurut prinsip pencocokan paling kiri, pencocokan berhenti jika operator>atau<digunakan dalam kueri SQL. Oleh karena itu, predikat pada kolomdatetidak dapat menggunakan kunci pengelompokan. Karena terdapat indeks bitmap pada kolomdate, kueri tersebut menggunakan indeks tersebut sebagai gantinya.SELECT * FROM ck_bit_test WHERE uid = '3' AND class >'2' AND date = '2022-10-17';Rencana eksekusi berisi operator
Cluster Filterdan operatorBitmap Filter. Hal ini menunjukkan bahwa kueri menggunakan kunci pengelompokan untuk kolomuid,classdan indeks bitmap untuk kolomdate.explain SELECT * FROM ck_bit_test WHERE uid = '3' AND class >'2' AND date = '2022-10-17'; QUERY PLAN Exchange (Gather Exchange) (cost=0.00..1.10 rows=1 width=24) -> Decode (cost=0.00..1.10 rows=1 width=24) -> Index Scan using holo_index:[1] on ck_bit_test (cost=0.00..1.00 rows=1 width=24) Cluster Filter: ((uid = 3) AND (class > '2'::text)) Bitmap Filter: (date = '2022-10-17'::text) Shard Selector(Eagerly): ->: l0 [3] Optimizer: HQO version 1.3.0
-
Contoh
-
Sintaks yang didukung oleh Hologres V2.1 dan versi lebih baru:
CREATE TABLE tbl ( a text NOT NULL, b text NOT NULL ) WITH ( bitmap_columns = 'a:on,b:off' ); -- Memodifikasi bitmap_columns ALTER TABLE tbl SET (bitmap_columns = 'a:off');-- Pernyataan ALTER TABLE hanya mendukung modifikasi penuh. -
Sintaks yang didukung oleh semua versi:
-- Membuat tabel tbl dan mengatur indeks bitmap. begin; create table tbl ( a text not null, b text not null ); call set_table_property('tbl', 'bitmap_columns', 'a:on,b:off'); commit; -- Memodifikasi indeks bitmap. call set_table_property('tbl', 'bitmap_columns', 'a:off');-- Modifikasi penuh, yang menonaktifkan indeks bitmap untuk kolom a. call update_table_property('tbl', 'bitmap_columns', 'b:off');-- Memodifikasi properti secara inkremental, menonaktifkan indeks bitmap untuk kolom b sambil mempertahankan pengaturan untuk kolom a.
Dokumen terkait
Topik berikut memberikan informasi lebih lanjut tentang pernyataan Data Definition Language (DDL) untuk tabel internal di Hologres: