Leitura de índices B-Tree: Alteração do Clustering Factor – Parte 2 (Reverse Key Index)

Tinha mostrado anteriormente que apenas reorganizando a tabela seria possível alterar o valor do CF e que  uma reorganização do índice nada poderia fazer, pois o CF depende directamente da desordem dos blocos na tabela comparada com a organização no índice. No entanto existe uma forma relativamente simples de alterar o valor do CF que é usando reverse key index (não sei o termo em português).

Existem alguns casos onde este tipo de índices é útil, que foram desenhados essencialmente para resolver o problema de contenção nos blocos (index block contention). Basicamente ocorrem em cenários de muita concorrência (DML insert, update ou delete) onde as várias sessões concorrentes precisam de aceder ao mesmo bloco (chamado “hot block”) gerando assim contenção ao nível do bloco do índice causando inumeros wait events do tipo “buffer busy waits”, por exemplo.

Mas o post não é sobre os Reverse Key Index, mas sim sobre o CF e como este valor pode ser alterado usando um índice reverted. A alteração da ordem no índice leva a que a desordem na tabela seja diferente. Como exemplo simples, se um ID para inserir na tabela for gerado como 112233 será inserido como 332211 no índice. Este tipo de “reverse” permite que os inserts sejam espalhados por toda a estrutura do índice, evitando a contenção em apenas um só leaf bloco (o mais há direita). Com isto fazemos com que as entradas no índice deixem de estar ordenadas da forma natural e como conhecemos, ou seja, o 112234 a seguir ao 112233.
Apesar de parecer resolver alguns problemas nomeadamente em ambientes RAC muito concorridos, cria uma outra panóplia de problemas que não discutiremos neste post.

O código seguinte mostrará uma tabela, um índice normal que depois será convertido para “reverse” e os respectivos
valores do CF após cada etapa:

 


SQL> create table t_cf2 as select ceil(dbms_random.value(0,100000)) N1 from dual connect by level <= 100000;

Table created.


SQL> create index i_cf2 on t_cf2(N1);

Index created.


SQL> exec dbms_stats.gather_table_stats(null,'T_CF2', cascade=>TRUE);

PL/SQL procedure successfully completed.


SQL> select blevel, leaf_blocks, clustering_factor from user_indexes where index_name = 'I_CF2';

BLEVEL LEAF_BLOCKS CLUSTERING_FACTOR
---------- ----------- -----------------
1 222 99270

SQL> alter index i_cf2 rebuild reverse;

Index altered.


SQL> select blevel, leaf_blocks, clustering_factor from user_indexes where index_name = 'I_CF2';

BLEVEL LEAF_BLOCKS CLUSTERING_FACTOR
---------- ----------- -----------------
1 222 99265

Temos uma valor diferente no CF, sendo que a diferença é pouca o que significa que o meu exemplo aqui não foi o melhor, no entanto, como nota final não devem de forma alguma usar os RKI sem cuidado, pois a ordem das chaves deixa de ser a natural e os “range scans” deixam de ser possíveis (predicados como BETWEEN, LIKE, > <) e o CBO vai por completo ignorar este tipo de índices. Estes dois posts sobre o CF foram apenas para fazer entender como o CF varia em função das várias ordens seja na tabela ou no índice.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s