Eu tenho uma tabela em que a cardinalidade dos planos parece muito alta - apesar de atualizar as estatísticas e até mesmo tentar a amostragem dinâmica para o Oracle 11gR2.
select count(*)
from table1
where col1 = 123
and col2 = '1';
A cardinalidade estimada para um valor de col1 é aproximadamente 29k, quando as linhas reais retornadas são 637. Para outro valor, sua cardinalidade planejada é 460k quando as linhas reais são 67k. Em geral, isso está fazendo com que ele escolha planos muito ruins.
Eu tentei atualizar as estatísticas:
exec DBMS_STATS.gather_table_stats (ownname => 'ME', tabname =>'table1');
ou
exec DBMS_STATS.gather_table_stats (ownname => 'ME', tabname =>'table1',estimate_percent =>100);
E eu tentei vários valores de dynamic_samping (1-10), mas nada muda significativamente:
select /*+ dynamic_sampling(t1 10) */ count(*)
from table1 t1
where col1 = 123
and col2 = '1';
dyanmic_sampling irá alterar, mas ainda está fora de quase um fator de 50-100 vezes.
Como posso obter estimativas melhores?
A primeira coisa que faria é verificar as estatísticas das colunas individualmente com estas consultas:
select count(*) from table1 where col1 = 123;
select count(*) from table1 where col2 = '1';
Se as cardinalidades estimadas aqui concordarem muito melhor com as contagens de linha reais, isso significa que há alguma correlação entre as colunas que o CBO não pode adivinhar com base nos histogramas gerados por um vanilla
gather_table_stats
. A amostragem dinâmica deve melhorar as coisas ao custo de maior tempo de análise, mas não é uma bala de prata.Como alternativa, com 11g, " O Oracle Database também pode reunir estatísticas sobre um grupo de colunas em uma tabela "