Quando uma tabela tem sua estatística atualizada, as estatísticas antigas ficam armazenadas na SM/OPTSTAT pelo período de retenção definido no ambiente.
Esta opção pode ser bastante útil quando temos alterações nas estatísticas de alguma tabela que geram algum problema de performance. Desta forma é possível facilmente voltar as estatísticas que estavam antes do "problema" ter acontecido. É claro se este período estiver dentro da retenção definida para o ambiente.
Primeiramente, vamos verificar qual a retenção padrão para as estatísticas em nosso ambiente. A verificação pode ser feita através da procedure dbms_stats.get_stats_history_availability e dbms_stats.get_stats_history_availability. Vale ressaltar que a retenção padrão das estatísticas no Oracle é de 31 dias.
lamimdb1@SYS> select dbms_stats.get_stats_history_retention from dual; GET_STATS_HISTORY_RETENTION --------------------------- 31 lamimdb1@SYS> select dbms_stats.get_stats_history_availability from dual; GET_STATS_HISTORY_AVAILABILITY --------------------------------------------------------------------------- 12-OCT-17 08.49.56.000000000 AM -02:00
Conforme verificado, nosso ambiente está configurado com a retenção padrão de 31 dias, com isso a data mais antiga para uma restauração de uma coleta é de 12/10/2017 as 08:48:56 horas.
Caso necessário, a alteração da retenção pode ser alterada de acordo com a necessidade. Para isso, basta definir a nova retenção através da procedure dbms_stats.alter_stats_history_retention.
Vamos alterar nossas estatísticas para 45 dias. É importante destacar que, quanto maior o período de retenção das estatísticas, mais área será necessária para armazenar essas informações na sysaux.
lamimdb1@SYS> exec dbms_stats.alter_stats_history_retention(45); PL/SQL procedure successfully completed. lamimdb1@SYS> select dbms_stats.get_stats_history_retention from dual; GET_STATS_HISTORY_RETENTION --------------------------- 45 lamimdb1@SYS>
Para demonstrar o processo, será criada uma tabela de testes STATISTICSTST cópia da dba_objects. Posteriormente será executada a coleta de estatísticas da mesma, de 2 formas. Uma com size auto e outra com size 1. Esta etapa é realizada apenas para fins de demonstração.
lamimdb1@SYS> create table statisticstst as select * from dba_objects; Table created. lamimdb1@SYS> execute DBMS_STATS.GATHER_TABLE_STATS (ownname => 'SYS',TABNAME =>'STATISTICSTST',estimate_percent => 100,method_opt => 'FOR ALL COLUMNS SIZE AUTO',degree => 5 ,granularity => 'ALL', cascade => TRUE, no_invalidate => FALSE); PL/SQL procedure successfully completed. lamimdb1@SYS> lamimdb1@SYS> lamimdb1@SYS> alter session set nls_date_format='dd/mm/yyyy hh24:mi:ss'; Session altered. lamimdb1@SYS> select last_analyzed from dba_tables where table_name='STATISTICSTST'; LAST_ANALYZED ------------------- 19/11/2017 21:52:03 lamimdb1@SYS> execute DBMS_STATS.GATHER_TABLE_STATS (ownname => 'SYS',TABNAME =>'STATISTICSTST',estimate_percent => 100,method_opt => 'FOR ALL COLUMNS SIZE 1',degree => 5 ,granularity => 'ALL', cascade => TRUE, no_invalidate => FALSE); PL/SQL procedure successfully completed. lamimdb1@SYS> select last_analyzed from dba_tables where table_name='STATISTICSTST'; LAST_ANALYZED ------------------- 19/11/2017 22:12:46 lamimdb1@SYS>
Agora vamos considerar que a ultima coleta realizada (22:12:46 horas) ocasionou uma degradação e um processo e será preciso realizar um rollback das estatísticas. Vamos consultar o histórico de estatísticas para a tabela STATISTICSTST e ver quais informações temos para poder realizar o rollback.
lamimdb1@SYS> set lines 210 select a.table_name, a.stats_update_time from DBA_TAB_STATS_HISTORY a where a.table_name='STATISTICSTST';lamimdb1@SYS> 2 TABLE_NAME STATS_UPDATE_TIME ------------------------------ --------------------------------------------------------------------------- STATISTICSTST 19-NOV-17 09.52.03.131616 PM -02:00 STATISTICSTST 19-NOV-17 10.12.46.653555 PM -02:00
É possível validar que temos no histórico as 2 coletas que realizamos. Estaremos realizando a restauração das estatísticas para as realizada as 21:52:03 horas, através da procedure dbms_stats.restore_table_stats onde passaremos o owner, table_name e data, conforme abaixo.
lamimdb1@SYS> select table_name, to_char(last_analyzed,'dd/mm/yyyy hh24:mi') last_analyzed from dba_tables where table_name='STATISTICSTST'; 2 TABLE_NAME LAST_ANALYZED ------------------------------ ---------------- STATISTICSTST 19/11/2017 22:12 lamimdb1@SYS> exec dbms_stats.restore_table_stats('SYS', 'STATISTICSTST','19-NOV-17 09.52.03.131616 PM -02:00'); PL/SQL procedure successfully completed. lamimdb1@SYS> select table_name, to_char(last_analyzed,'dd/mm/yyyy hh24:mi') last_analyzed from dba_tables where table_name='STATISTICSTST'; 2 TABLE_NAME LAST_ANALYZED ------------------------------ ---------------- STATISTICSTST 19/11/2017 21:52
Fonte: https://docs.oracle.com/cd/E18283_01/appdev.112/e16760/d_stats.htm#i1048566
Comentários
Postar um comentário