Pular para o conteúdo

BITMAP em alta cardinalidade?

BITMAP em alta cardinalidade?

Os índices BITMAP podem ser úteis sim, em colunas com cardinalidade maior.

Veja no teste abaixo, onde utilizei uma coluna com cardinalidade bem maior (de 28/10936000 para 40998/10936000), e pelo menos para agregações, a performance com BITMAP foi muito melhor (3x) do que o Índice BTREE. O ganho foi muito menor do que na cardinalidade menor, demonstrada no teste anterior, mas mesmo assim um ganho de 300% é muito bom.

SQL> SELECT COUNT(1) FROM T;

COUNT(1)
----------
10936000

Decorrido: 00:00:00.03
SQL> SELECT COUNT(DISTINCT(OWNER)) FROM T;

COUNT(DISTINCT(OWNER))
----------------------
28

Decorrido: 00:00:01.87
SQL> SELECT COUNT(DISTINCT(OBJECT_NAME)) FROM T;

COUNT(DISTINCT(OBJECT_NAME))
----------------------------
40998

Decorrido: 00:00:26.03
SQL> CREATE INDEX T_IDX2_BTREE ON T(OBJECT_NAME);

-ndice criado.

Decorrido: 00:03:37.48
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'T', CASCADE=>TRUE);

Procedimento PL/SQL concluÝdo com sucesso.

Decorrido: 00:01:00.10
SQL> SELECT COUNT(DISTINCT(OBJECT_NAME)) FROM T;

COUNT(DISTINCT(OBJECT_NAME))
----------------------------
40998

Decorrido: 00:00:09.90
SQL> SELECT COUNT(DISTINCT(OBJECT_NAME)) FROM T;

COUNT(DISTINCT(OBJECT_NAME))
----------------------------
40998

Decorrido: 00:00:09.01
SQL> SELECT COUNT(DISTINCT(OBJECT_NAME)) FROM T;

COUNT(DISTINCT(OBJECT_NAME))
----------------------------
40998

Decorrido: 00:00:08.95
SQL> DROP INDEX T_IDX2_BTREE;

-ndice eliminado.

Decorrido: 00:00:00.37
SQL> CREATE BITMAP INDEX T_IDX2_BTREE ON T(OBJECT_NAME);

-ndice criado.

Decorrido: 00:00:43.67
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'T', CASCADE=>TRUE);

Procedimento PL/SQL concluÝdo com sucesso.

Decorrido: 00:01:02.87
SQL> SELECT COUNT(DISTINCT(OBJECT_NAME)) FROM T;

COUNT(DISTINCT(OBJECT_NAME))
----------------------------
40998

Decorrido: 00:00:03.14
SQL> SELECT COUNT(DISTINCT(OBJECT_NAME)) FROM T;

COUNT(DISTINCT(OBJECT_NAME))
----------------------------
40998

Decorrido: 00:00:02.45
SQL> SELECT COUNT(DISTINCT(OBJECT_NAME)) FROM T;

COUNT(DISTINCT(OBJECT_NAME))
----------------------------
40998

Decorrido: 00:00:03.15
SQL>

Tempo do COUNT DISTINCT com índice BTREE: 9 segundos, 9 segundos e 8 segundos.

Tempo do COUNT DISTINCT com índice BITMAP: 3 segundos, 2 segundos e 3 segundos.

Então, devemos ter cuidado com o que chamamos de alta cardinalidade. Testar é sempre a melhor opção.

Ricardo Portilho Proni

Ricardo Portilho Proni

Com 20 anos de experiência profissional, Oracle ACE Member – eleito pela Oracle Corporation um dos maiores especialistas do mundo em Oracle Database- Trabalhou em grande parte dos maiores bancos de dados Oracle do Brasil. Certificado em Oracle, SQL Server, DB2, MySQL, Sybase e Websphere. Conselheiro do GPO e do GUOB, palestrante do ENPO, GUOB Tech Day e Oracle Open World, escritor da Revista SQL Magazine e Instrutor na Nerv.

Comentário(s) da Comunidade

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress