CF este ilustre informante…

Imagine um select em que o filtro possa ser atendido por 2 ou mais índices, como o Oracle faz para escolher qual deverá usar?

O CF têm a função de desempate quando mais de um índice atende a condição, optando sempre pelo de menor valor.

Existem mais 2 conceitos importantes para o entendimento do CF, as tabelas (comum) armazenam os dados em heap, ou seja, de forma não ordenada e com o índice ocorre o mesmo. Com isto pode acontecer em uma leitura de um índice o salto entre blocos e que pode saltar mais de uma vez ao mesmo bloco.

Para exemplificar, para uma Tabela X que possui 2 blocos e os dados 1,2,3,4,5,6,7 e 8 temos um índice comum (btree) abaixo. Para uma leitura ordenada o índice fará 4 saltos (entre os blocos).

O percurso seria Bloco 1 (1,2,3) –> Bloco 2 (4) –> Bloco 1(5) –> Bloco 2 (6,7) –> Bloco 1(8). Neste caso nosso o índice teria um CF de 5, que é o número de saltos (entre blocos) + 1.

Na dba_indexes existe uma coluna chamada clustering_factor (CF) e é alimentada pelo processo de cálculo de estatísticas.

Este valor indica o número de blocos que serão acessados numa operação de index scan.

Obs.: as operações lookup/key read, tipicamente PKs e UK, primary key e unique respectivamente, são tratados de forma distinta.

O valor do CF quanto mais próximo ao número de blocos da tabela, melhor, dá a entender que o índice está organizado em relação a tabela.

Isso explica, por exemplo, quando recriamos uma tabela com “create table as select * from x order by col_a”, qualquer índice com a coluna col_a terá um CF próximo ao número de blocos da tabela x. Em consequência, as demais colunas não terão um CF tão favorável (que não siginifica que seja pessímo).

Exemplo prático:

  • Vamos criar uma tabela e dois índices que serão utilizados nos testes:

  • Cálculo de estatísticas para a tabela, como a volumetria é pequena, acabam que os índices terão um CF pequeno e em igual valor.

  • Vamos alterar o valor do CF com o dbms_stats.set_index_stats para 100:

  • Com a alteração o IDX2 terá um CF menor que o IDX1, portanto o IDX2 será utilizado, como se pode ver no plano de execução abaixo:

  • Agora, vamos alterar o CF para IDX2 para o valor 1000:

  • Agora com o IDX1 com um valor menor, será utilizado, o que se pode ver novo plano abaixo:

O ditado “cortar o mal pela raiz” aqui faz sentido, em que um bom modelo de dados pode prevenir uma série de problemas de performance 🙂 🙂

Saudações Vascaínas….

Um comentário em “CF este ilustre informante…

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s