A coleta de estatísticas de forma incremental foi introduzida a partir da versão 11g, para melhorar a performance da coleta de estatística de grandes tabelas particionadas.
Nas tabelas particionadas, geralmente os novos dados são inseridos em uma nova partição. Quando uma nova partição é adicionada e os dados inseridos, as estatísticas da nova partição deve ser coletada e as estatísticas globais também devem ser atualizadas. Esse processo em grandes tabelas particionadas pode ser de grande impacto no ambiente uma vez que quanto mais partições são inseridas maior será o tempo de coleta devido ao full table scan realizado para atualização das estatísticas globais.
Com a coleta incremental ativada (ativação a nível de tabela) e a coleta é realizada com o parâmetro GRANULARITY AUTO, o Oracle realizada a coleta de estatística da nova partição e atualizará a estatística global apenas com as informações das partições modificadas, ao invés de atualizar as informações de todas as partições existentes (realizando um full table scan).
Vamos a prática..
Estarei realizando uma demonstração utilizando uma tabela com 38 partições existentes, e uma tamanho de 41,5 MB.
Conforme podemos contatar acima, a coleta desta tabela não executará de forma incremental. Posteriormente, executamos uma coleta de estatística da tabela para mensurar o tempo de execução, que foi de 21,28 segundos.
Vale ressaltar alguns pontos importantes sobre esse processo:
Estarei realizando uma demonstração utilizando uma tabela com 38 partições existentes, e uma tamanho de 41,5 MB.
LAMIMTST1@SYS> select table_owner, table_name, count(1) from dba_tab_partitions where table_name='TABLE_PART_LAMIM' group by table_name, table_owner; TABLE_OWNER TABLE_NAME COUNT(1) ------------------------------ ------------------------------ ---------- LAMIM TABLE_PART_LAMIM 38 LAMIMTST1@SYS> select sum(bytes/1024/1024) from dba_segments where segment_name='TABLE_PART_LAMIM'; SUM(BYTES/1024/1024) -------------------- 41.5 Elapsed: 00:00:00.14Primeiramente, vamos verificar através do comando dbms_stats.get_prefs se a tabela TABLE_PART_LAMIM está com o parâmetro FALSE (desativado) ou TRUE (ativado) para as coletas incrementais.
LAMIMTST1@SYS> SELECT dbms_stats.get_prefs(ownname=>'LAMIM',pname=>'INCREMENTAL',tabname=>'TABLE_PART_LAMIM') FROM DUAL; DBMS_STATS.GET_PREFS(OWNNAME=>'LAMIM',PNAME=>'INCREMENTAL',TABNAME=>'TABLE_PART_LAMIM -------------------------------------------------------------------------------- FALSE
LAMIMTST1@SYS> begin 2 DBMS_STATS.GATHER_TABLE_STATS ( 3 ownname => 'LAMIM', 4 TABNAME =>'TABLE_PART_LAMIM', 5 estimate_percent => dbms_stats.auto_sample_size, 6 method_opt => 'FOR ALL COLUMNS SIZE AUTO', 7 degree => 5 , 8 granularity => 'ALL', 9 cascade => TRUE, 10 no_invalidate => FALSE); 11 end; 12 / PL/SQL procedure successfully completed. Elapsed: 00:00:21.28 LAMIMTST1@SYS> LAMIMTST1@SYS>
Agora vamos definir o parâmetro incremental como TRUE e verificar o tempo de execução para que possamos comparar.
exec dbms_stats.set_table_prefs('LAMIM','TABLE_PART_LAMIM','INCREMENTAL','TRUE'); PL/SQL procedure successfully completed. Elapsed: 00:00:00.18
LAMIMTST1@SYS> SELECT dbms_stats.get_prefs(ownname=>'LAMIM',pname=>'INCREMENTAL',tabname=>'TABLE_PART_LAMIM') FROM DUAL; DBMS_STATS.GET_PREFS(OWNNAME=>'DW',PNAME=>'INCREMENTAL',TABNAME=>'FATOCLASSIFICA -------------------------------------------------------------------------------- TRUEAgara que definimos a opção INCREMENTAL para nossa tabela particionada, vamos efetuar uma nova coleta de estatísticas para mensurar novo tempo de execução.
LAMIMTST1@SYS> begin 2 DBMS_STATS.GATHER_TABLE_STATS ( 3 ownname => 'LAMIM', 4 TABNAME =>'TABLE_PART_LAMIM', 5 estimate_percent => dbms_stats.auto_sample_size, 6 method_opt => 'FOR ALL COLUMNS SIZE AUTO', 7 degree => 5 , 8 granularity => 'ALL', 9 cascade => TRUE, 10 no_invalidate => FALSE); 11 end; 12 / PL/SQL procedure successfully completed. Elapsed: 00:00:6.31 LAMIMTST1@SYS> LAMIMTST1@SYS>Conforme pode ser validado na execução acima, o ganho no tempo de execução com a coleta incremental é bastante expressivo, representando um ganho de 70,35%.
Vale ressaltar alguns pontos importantes sobre esse processo:
- Para que o processo de coleta execute de modo incremental, o valor do parâmetro estimate_percent deve estar definido como dbms_stats.auto_sample_size.
- Sempre que uma tabela particionada é definida para execução da coleta incremental, sempre que houver uma alteração DML em uma partição ou subpartição a mesma será marcada para que a mesma seja coletada na próxima execução da rotina.Ou seja, não é levado em consideração o valor do stale_percent.
- A partir da versão 12c já é possível utilizar a coleta incremental junto com a definição de uma porcentagem de modificações (stale_percent).
Fonte:
https://docs.oracle.com/cd/B28359_01/server.111/b28274/stats.htm#i37048
https://blogs.oracle.com/optimizer/efficient-statistics-maintenance-for-partitioned-tables-using-incremental-statistics-part-1
https://blogs.oracle.com/optimizer/efficient-statistics-maintenance-for-partitioned-tables-using-incremental-statistics-part-1
Comentários
Postar um comentário