Perigos e Armadilhas do Particionamento - Etapa 2 – Parte 02

por Arup Nanda 

Estatísticas de Subpartições

Esta é uma parte enganadora do subparticionamento que não é bem e claramente documentada nos manuais. O pacote DBMS_ESTATÍSTICAS já deve ter sido usado por tempo suficiente para ter coletado estatísticas. Para coletar estatísticas para as tabelas e para seus sub-objetos (por exemplo, partições e sub-partições), deveríamos usar a função contida no pacote GATHER_TABLE_ESTATÍSTICAS. A função tem dois parâmetros pouco conhecidos que devem ser designados para coletar as estatísticas. 

PARTNAME  

Este parâmetro é supostamente designado para coletar estatísticas só para a partição nomeada dentro da tabela e não para a tabela inteira. Porém, este é um engano. PARTNAME pode ser usado para coletar estatísticas também para uma sub-partição específica. Para assim faze-lo, o nome da sub-partição é passado neste parâmetro. 

GRANULARITY  

Este parâmetro instrui o pacote para coletar estatísticas em níveis diferentes e aplica-los em cascata a outros sub-objetos. Aceita vários valores. O padrão, chamado DEFAULT, instrui o pacote para coletar estatísticas globais e somente nas partições. O valor de PARTITION instrui o pacote para coletar estatísticas a nível de partição. Porém, atribuindo estes valores não serão coletadas estatísticas a nível de sub-partição; estes podem ser coletadas designando o valor do parâmetro para ALL ou SUBPARTITON. 

Consideremos a tabela criada como segue: 

create table spart1
(
   col1    number,
   col2    number,
   col3    varchar2(20)
)
partition by range (col1)
subpartition by hash (col2)
sub-partições 4
(
   partition p1 values less than (101),
   partition p2 values less than (201),
   partition p3 values less than (301),
   partition p4 values less than (401),
   partition pm values less than (maxvalue)

)

Analisemos a tabela que usa o valor padrão de granularidade como segue:

exec dbms_estatísticas.gather_table_estatísticas (tabname=>'SPART1')

Note-se que não informamos a granularidade. Desde que o valor padrão é para coletar estatísticas para as partições e não para qualquer sub-partição, as estatísticas não serão coletadas para as sub-partições. Isto pode ser verificado rodando:

select partition_name
from user_tab_subpartitions
where last_analyzed is not null;

Este comando não retornará nenhuma linha. Mas analisemos as outras opções aqui. Uma tabela pode ter estatísticas a nível de tabela somente, chamadas estatísticas GLOBAIS (GLOBAL statistics). Se forem analisadas as partições da tabela e o otimizador consegue derivar as estatísticas globais das partições individuais, então se supõe que as estatísticas para a tabela serão derivadas globalmente. Examinemos cada opção em detalhes: 

exec dbms_stats.gather_table_stats (tabname=>'SPART1', granularity=>'GLOBAL')

 

Este comando coleta estatísticas somente a nível global. A consulta a seguir confirma isto. 

Select last_analyzed, global_stats

From user_tables where table_name = 'SPART1';

Isto retorna

GLO LAST_ANAL

--- ---------

YES 10-MAR-03


A presença de estatísticas globais indica que a tabela foi analisada como um todo, mas o otimizador não terá conhecimento das estatísticas de partições individuais. Estas estatísticas podem ser coletadas utilizando o seguinte comando:

exec dbms_stats.gather_table_stats (tabname=>'SPART1', granularity=>'PARTITION')

Este comando coleta as estatísticas apenas a nível de partição. Neste caso, as estatísticas globais não são coletadas na tabela e a consulta retornará um NO debaixo de GLOBAL_STATS. Porém, a consulta.

select partition_name, last_analyzed
from user_tab_partitions
where last_analyzed is not null;

recuperará todas as partições. Outra variação do pacote é mostrada abaixo. 

exec dbms_stats.gather_table_stats (tabname=>'SPART1', granularity=>'SUBPARTITION')

 

Isto coleta estatísticas somente a nível de sub-partição e deduz as estatísticas ao nível de partição; porém, não coleta estatísticas globais nas partições. 

O último valor da opção, ALL, executa todos estes – tanto coleta estatísticas a nível de partição e sub-partição, como também estatísticas globais na sub-partição, partição e tabela. 

Assim, o valor padrão para o parâmetro GRANULARITY na função de coleta de estatísticas, não coleta estatísticas em sub-partições; é preciso configura-lo para SUBPARTITION ou ALL para coletar estatísticas. 

Em resumo, estes são os detalhes sobre atribuir granularidade e coletar estatísticas:

pb_28_05_09_pic02.JPG

Outro conceito interessante que não é documentado claramente é a opção para só analisar sub-partições. Isto pode ser feito usando-se:

exec dbms_stats.gather_table_stats (tabname=>'SPART1', PART_NAME=>'P1_SYS123')

Este comando só colecionará estatísticas a nível de sub-partition somente na sub-partição P1_SYS123.