Este tópico descreve como usar índices bitmap no Hologres.
Visão geral
No Hologres, a propriedade bitmap_columns define um índice bitmap. Essa estrutura de índice é independente do armazenamento de dados e acelera consultas de igualdade. O índice usa um vetor de bits para filtrar rapidamente os dados nos blocos de arquivos, sendo ideal para cenários de filtragem por igualdade. Use a seguinte sintaxe:
-- Syntax supported by Hologres V2.1 and later
CREATE TABLE <table_name> (...) WITH (bitmap_columns = '[<columnName>{:[on|off]}[,...]]');
-- Syntax supported by all versions
CREATE TABLE <table_name> (...);
CALL set_table_property('<table_name>', 'bitmap_columns', '[<columnName>{:[on|off]}[,...]]');
|
Parâmetro |
Descrição |
|
table_name |
Nome da tabela. |
|
columnName |
Nome da coluna. |
|
on |
Ativa o índice bitmap na coluna especificada. |
|
off |
Desativa o índice bitmap na coluna especificada. |
Recomendações
Crie índices bitmap em colunas usadas frequentemente em consultas de igualdade. Isso permite que o sistema localize rapidamente os números das linhas correspondentes. No entanto, usar esses índices em colunas de alta cardinalidade (com poucos valores duplicados) pode gerar sobrecarga significativa de armazenamento.
Evite criar índices bitmap em todas as colunas. Essa prática aumenta o custo de armazenamento e reduz o throughput de escrita, pois o Hologres precisa construir um índice para cada coluna durante a ingestão de dados.
Não crie índices bitmap em colunas de texto que armazenam dados no formato JSON.
Limitações
O Hologres oferece suporte a índices bitmap em tabelas orientadas a colunas e híbridas (linha-coluna), mas não em tabelas orientadas a linhas.
Colunas com índice bitmap podem conter valores nulos.
Por padrão, o sistema cria índices bitmap implicitamente em todas as colunas do tipo de dados text.
Execute comandos para definir índices bitmap fora de uma transação. As alterações não entram em vigor imediatamente, pois o Hologres cria e exclui as codificações bitmap de forma assíncrona em segundo plano. Para mais informações, consulte ALTER TABLE.
A propriedade
bitmap_columnsaceita apenasonouoff. A partir do Hologres V2.0, não há mais suporte para definir a propriedadebitmap_columnscomoauto.
Funcionamento
Diferentemente de uma chave de distribuição ou de clustering, o índice bitmap é uma estrutura independente do armazenamento de dados. Quando uma consulta usa esse índice, ela localiza rapidamente o número da linha para filtrar os dados. Contudo, índices bitmap geram sobrecarga. Considere os seguintes cenários:
Colunas com alta cardinalidade: o Hologres gera um bitmap para cada valor distinto. Se houver muitos valores não repetidos, esse processo forma um array esparso que consome grande quantidade de armazenamento.
Todas as colunas de uma tabela larga possuem índices bitmap: se você criar um índice bitmap para cada coluna de uma tabela larga, o Hologres precisará construir um bitmap para cada valor durante a ingestão de dados. Isso cria sobrecarga no sistema e reduz o throughput de escrita.
Em resumo, o índice bitmap representa uma troca de espaço por tempo. Ele é mais eficiente em termos de custo para colunas com distribuição de dados relativamente uniforme.
Conforme mostrado no exemplo a seguir, use explain SQL para verificar se uma consulta usa um índice bitmap. Se o plano de execução contiver Bitmap Filter, a consulta usou o índice.
-
Sintaxe compatível com o Hologres V2.1 e versões posteriores:
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'; -
Sintaxe compatível com todas as versões:
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';
A presença do operador Bitmap Filter no plano de execução, como Bitmap Filter: (gender = 'Male'::text) AND (class = 'Class 1'::text), confirma que a consulta usou o índice bitmap.
Índice bitmap vs. chave de clustering
Tanto os índices bitmap quanto as chaves de clustering filtram dados dentro dos arquivos.
-
Índices bitmap são ideais para consultas de igualdade porque localizam dados pelo número da linha. Por outro lado, as chaves de clustering ordenam os dados nos arquivos, sendo mais adequadas para consultas de intervalo.
Uma chave de clustering tem prioridade maior que um índice bitmap. Se ambos forem criados na mesma coluna, o otimizador prefere usar a chave de clustering. O exemplo a seguir mostra os detalhes:
-
Sintaxe compatível com o Hologres V2.1 e versões posteriores:
-- The uid, class, and date columns are set as the clustering key. -- By default, text columns such as name, class, and date have bitmap indexes. 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'); -
Sintaxe compatível com todas as versões:
-- The uid, class, and date columns are set as the clustering key. -- By default, text columns such as name, class, and date have bitmap indexes. 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');
-
Esta consulta de igualdade tem como alvo as colunas
uid,class,date. Como segue o princípio de correspondência mais à esquerda, o otimizador usa a chave de clustering em vez do índice bitmap.SELECT * FROM ck_bit_test WHERE uid = '3' AND class ='2' AND date > '2022-10-17';O plano de execução contém o operador
Cluster Filter, mas não o operadorBitmap Filter, indicando que a consulta usou a chave de clustering. O plano mostra umIndex Scan using holo_index:[1] on ck_bit_teste filtra usandoCluster Filter: ((uid = 3) AND (class = '2'::text) AND (date > '2022-10-17'::text)), o que confirma o uso da chave de clustering. -
A consulta é executada nas colunas
uid,class,date. No entanto, a colunaclassé usada em uma consulta de intervalo. De acordo com o princípio de correspondência mais à esquerda, a correspondência para se>ou<for usado em uma consulta SQL. Portanto, o predicado na colunadatenão pode usar a chave de clustering. Como existe um índice bitmap na colunadate, a consulta o utiliza em vez da chave.SELECT * FROM ck_bit_test WHERE uid = '3' AND class >'2' AND date = '2022-10-17';O plano de execução contém tanto o operador
Cluster Filterquanto o operadorBitmap Filter. Isso indica que a consulta usou a chave de clustering para as colunasuid,classe o índice bitmap para a colunadate.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
-
Exemplos
-
Sintaxe compatível com o Hologres V2.1 e versões posteriores:
CREATE TABLE tbl ( a text NOT NULL, b text NOT NULL ) WITH ( bitmap_columns = 'a:on,b:off' ); -- Modify bitmap_columns ALTER TABLE tbl SET (bitmap_columns = 'a:off');-- The ALTER TABLE statement supports only full modification. -
Sintaxe compatível com todas as versões:
-- Create the tbl table and set a bitmap index. begin; create table tbl ( a text not null, b text not null ); call set_table_property('tbl', 'bitmap_columns', 'a:on,b:off'); commit; -- Modify the bitmap index. call set_table_property('tbl', 'bitmap_columns', 'a:off');-- Full modification, which disables the bitmap index for column a. call update_table_property('tbl', 'bitmap_columns', 'b:off');-- Incrementally modifies the property, disabling the bitmap index for column b while retaining the setting for column a.
Documentos relacionados
Os tópicos a seguir fornecem mais informações sobre instruções de Linguagem de Definição de Dados (DDL) para tabelas internas no Hologres: