Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como verificar estatísticas obsoletas


As estatísticas podem ficar obsoletas quando os dados na tabela mudam substancialmente. Estatísticas atualizadas são importantes para gerar bons planos de execução

Como a Oracle decide se as estatísticas se tornaram obsoletas


As estatísticas são consideradas obsoletas quando #(INSERTS + UPDATES + DELETES)>=10% de NUM_ROWS de dba_tables:

Configuração de parâmetro necessária para acompanhar as alterações da tabela


Antes do Oracle 10g, a coleta automatizada de estatísticas para objetos que se tornaram obsoletos era controlada pela configuração do sinalizador MONITORING na tabela.
Dependendo do sinalizador MONITORING, o trabalho GATHER_STATS_JOB coletava “GATHER EMPTY” e “GATHER STALE” nos objetos sinalizados.

Em 10g, as palavras-chave MONITORING e NOMONITORING estão obsoletas e serão ignoradas. O recurso de monitoramento de tabela agora é controlado pelo parâmetro STATISTICS_LEVEL.

Quando STATISTICS_LEVEL é configurado como BASIC, o monitoramento é desabilitado na tabela.
Quando STATISTICS_LEVEL é configurado como TYPICAL, então o monitoramento é habilitado.
Por padrão, STATISTICS_LEVEL é configurado como TYPICAL e o monitoramento de tabelas é habilitado. É altamente recomendável definir STATISTICS_LEVEL como TYPICAL em 10g e acima
Ao definir esses parâmetros, o Oracle rastreia o número aproximado de operações INSERT, UPDATE e DELETE para a tabela do Oracle desde a última vez em que as estatísticas foram coletadas. Essas informações sobre “alterações feitas” são mantidas no SGA e periodicamente (a cada 15 minutos) o SMON libera os dados nas tabelas do dicionário de dados. Você pode liberar manualmente as informações chamando dbms_stats.FLUSH_DATABASE_MONITORING_INFO(). As informações do dicionário de dados ficam visíveis através das visualizações:DBA_TAB_MODIFICATIONS, ALL_TAB_MODIFICATIONS e USER_TAB_MODIFICATIONS.

A Oracle usa essas visualizações para identificar tabelas que possuem estatísticas obsoletas.
Sempre que houver 10% de alteração nos dados em uma tabela, a Oracle considera suas estatísticas obsoletas.

Como verificar estatísticas obsoletas


O procedimento PLSQL abaixo descobre todas as tabelas no esquema SCOTT, que são estatísticas obsoletas
SET SERVEROUTPUT ON

SQL> DECLARE
ObjList dbms_stats.ObjectTab;
BEGIN
DBMS_STATS.GATHER_SCHEMA_STATS(ownname=>'SCOTT', objlist=>ObjList, options=>'LIST STALE');
FOR k in ObjList.FIRST..ObjList.LAST
LOOP
dbms_output.put_line(ObjList(k).ownname || '.' || ObjList(k).ObjName || ' ' || ObjList(k).ObjType || ' ' || ObjList(k).partname);
END LOOP;
END;
/

O sql abaixo também pode ser usado para descobrir inserir, atualizar, excluir
select u.TIMESTAMP,
t.last_analyzed,
u.table_name,
u.inserts,
u.updates,
u.deletes,
d.num_rows,
decode(d.num_rows,0,'Table Stats indicate No Rows',
nvl(TO_CHAR(((U.inserts+u.deletes+u.updates)/d.num_rows) * 100,'999.99')
,'Null Value in USER_TAB_MODIFICATIONS')
) percent
from user_tables t,USER_TAB_MODIFICATIONS u,dba_tables d
where u.table_name = t.table_name
and d.table_name = t.table_name
and d.owner = '&Owner'
and (u.inserts > 3000 or u.updates > 3000 or u.deletes > 3000)
order by t.last_analyzed
/

Se você quiser executar isso no banco de dados inteiro
SET SERVEROUTPUT ON

SQL> DECLARE
ObjList dbms_stats.ObjectTab;
BEGIN
DBMS_STATS.GATHER_DATABASE_STATS(objlist=>ObjList, options=>'LIST STALE');
FOR k in ObjList.FIRST..ObjList.LAST
LOOP
dbms_output.put_line(ObjList(k).ownname || '.' || ObjList(k).ObjName || ' ' || ObjList(k).ObjType || ' ' || ObjList(k).partname);
END LOOP;
END;
/

Se você quiser ver as tabelas onde as estatísticas estão vazias, podemos usar abaixo
SET SERVEROUTPUT ON

SQL> DECLARE
ObjList dbms_stats.ObjectTab;
BEGIN
DBMS_STATS.GATHER_DATABASE_STATS(objlist=>ObjList, options=>'LIST EMPTY');
FOR k in ObjList.FIRST..ObjList.LAST
LOOP
dbms_output.put_line(ObjList(k).ownname || '.' || ObjList(k).ObjName || ' ' || ObjList(k).ObjType || ' ' || ObjList(k).partname);
END LOOP;
END;
/

Agora, depois de encontrar a lista de tabelas, você pode gerar estatísticas sobre essas tabelas.
exec dbms_stats.gather_table_stats('OWNER', 'TABLE_NAME');

Também podemos executar o comando abaixo para gerar estatísticas em todo o objeto obsoleto no esquema
exec dbms_stats.gather_schema_stats(ownname => '<schema name>', cascade => TRUE, options => 'GATHER AUTO');

A partir do Oracle11g, o limite de inatividade pode ser definido usando a preferência de estatísticas STALE_PERCENT. Isso pode ser definido globalmente usando DBMS_STATS.SET_GLOBAL_PREFS ou no nível da tabela usando DBMS_STATS.SET_TABLE_PREFS.

Artigos relacionados

ora-38029:as estatísticas do objeto estão bloqueadas
ora-20001 em Reunir estatísticas de esquema em 11g(FND_HISTOGRAM_COLS)
Reunir estatísticas na versão 11i e R12
Reunir estatísticas incrementais em 11g
Como definir Monitoramento de Tabela no Oracle e Relacionamento com STATISTICS_LEVEL