Leitura de índices B-Tree: A teoria e prática simplificada do Clustering Factor

O aviso:

 

É bastante comum, e má prática no geral dizer que um bom índicetem um baixo clustering_factor e um mau índice tem um alto clustering_factor.
Obviamente que em determinados casos isto acontece realmente e esta assunção é verdadeira. No entanto o valor em si, desprendido de outras comparações é completamente inútil na avaliação da qualidade do índice, pois um valor de por exemplo 1000 no clustering_factor será óptimo para uma tabela com 1000 blocos, provavelmente péssimo para uma tabela com 10 blocos.
Assim, o clustering_factor não é mais que uma métrica que compara a ordem no índice com o grau de desordem na tabela, ou seja, para calcular o clustering_factor o CBO navega na tabela pela ordem do  índice(muito importante) e regista quantas vezes salta de um bloco para outro na tabela. Cada vez que existe um salto, o valor do clustering_factor aumenta.
Este contador vai servir ao Oracle para decidir o custo associado ao uso do índice(range scan/full) em comparação com um full table scan.

A representação:

A imagem abaixo representa um MAU clustering_factor. A primeira entrada do índiceaponta para o primeiro bloco, a segunda entrada do índiceaponta para para o segundo bloco na tabela, a terceira entrada para o terceiro bloco e etc. Podem assim verificar o quão espanhados estão os dados fisicamente, o que obriga num index range scan ou full index scan, o CBO a saltar de um bloco para o outro e a visitar o mesmo bloco várias vezes pois os dados estão espalhados. Como sabem o I/O é caro e paga-se bastante caro por um  clustering_factor alto. Cada vez que há este salto aumenta o VALOR do clustering_factor.

Neste caso, a imagem abaixo representa um BOM clustering_factor, numa leitura do índiceo CBO não tem que saltar de bloco em bloco, já que as entradas do índiceapontam para o mesmo bloco.

 

A interpretação:

Para exemplo prático, vamos usar o índicee tabela criados anteriormente e verificar o clustering_factor associado.


SQL> select index_name, clustering_factor from user_indexes where index_name = 'I1';

INDEX_NAME CLUSTERING_FACTOR
------------------------------ -----------------
I1 372


SQL> column segment_name format a14
SQL> select segment_name, blocks from user_segments where segment_name = 'INDX_CON1';

SEGMENT_NAME BLOCKS
-------------- ----------
INDX_CON1 384


SQL> select count(1) from indx_con1;

COUNT(1)
----------
200000

Como interpretar isto o clustering_factor:

1 – Normalmente o clustering_factor está entre o número de blocos da tabela e o número de registos de uma tabela, o que
no nosso caso não se verifica. Ver ponto 2)

2 – Um clustering_factor pode ser menor que o número de blocos na tabela se existem blocos vazios na tabela abaixo
da HWM (High Water Mark), ou existem muitos registos null para as colunas indexadas. Vejamos:


SQL> select count(*) from indx_con1 where R0 is null;

COUNT(*)
----------
0

Confirmamos facilmente que as colunas indexadas (R0) não teem valores null, logo assumimos que o valor do
clustering_factor é abaixo do número de blocos pois existem blocos vazios abaixo da HWM.

3- O clustering_factor nunca pode ser maior que o número de registos na tabela.

4 – Um BOM clustering_factor é igual (ou abaixo, como o caso) ao valor do número de blocos da tabela.
5 – Um MAU clustering_factor é igual, ou próximo ao valor do número de registos na tabela.

6 – Caso o clustering_factor seja MAU (próximo do valor do número de registos) é provavel que o índicenão
seja escolhido pelo CBO, a não ser que a selectividade seja muito alta.

7 – Reorganizar um índicenão altera o clustering_factor, apenas a reorganização da tabela o permite, ordenando
os dados conforme a ordem do índice.

8 – É possível ajustar o clustering_factor MANUALMENTE com o uso do package DBMS_STATS.SET_INDEX_STATS.

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