Le statistiche possono diventare obsolete quando i dati nella tabella cambiano in modo sostanziale. Le statistiche aggiornate sono importanti per generare buoni piani di esecuzione
Come Oracle decide se le statistiche sono diventate obsolete
Le statistiche sono considerate obsolete quando #(INSERTS + UPDATES + DELETES)>=10% di NUM_ROWS da dba_tables:
Impostazione dei parametri richiesta per tenere traccia delle modifiche alla tabella
Prima di Oracle 10g, la raccolta automatizzata di statistiche per oggetti che erano diventati obsoleti era controllata dall'impostazione del flag MONITORING sulla tabella.
A seconda del flag MONITORING, il lavoro GATHER_STATS_JOB raccoglieva "GATHER EMPTY" e "GATHER STALE" sugli oggetti contrassegnati.
In 10g le parole chiave MONITORING e NOMONITORING sono obsolete e verranno ignorate. La funzione di monitoraggio delle tabelle è ora controllata dal parametro STATISTICS_LEVEL.
Quando STATISTICS_LEVEL è impostato su BASIC, il monitoraggio è disabilitato sulla tabella.
Quando STATISTICS_LEVEL è impostato su TYPICAL, il monitoraggio è abilitato.
Per impostazione predefinita STATISTICS_LEVEL è impostato su TYPICAL e il monitoraggio delle tabelle è abilitato. Si consiglia vivamente di impostare STATISTICS_LEVEL su TYPICAL in 10g e oltre
Impostando questi parametri, Oracle tiene traccia del numero approssimativo di operazioni INSERT, UPDATE ed DELETE per la tabella Oracle dall'ultima volta che sono state raccolte le statistiche. Queste informazioni sulle "modifiche apportate" sono mantenute nell'SGA e periodicamente (ogni 15 minuti circa) lo SMON scarica i dati nelle tabelle del dizionario dei dati. Puoi svuotare manualmente le informazioni chiamando dbms_stats.FLUSH_DATABASE_MONITORING_INFO(). Le informazioni del dizionario dei dati sono rese visibili attraverso le viste:DBA_TAB_MODIFICATIONS, ALL_TAB_MODIFICATIONS e USER_TAB_MODIFICATIONS.
Oracle utilizza queste viste per identificare le tabelle con statistiche non aggiornate.
Ogni volta che si verifica una variazione del 10% dei dati in una tabella, Oracle considera le sue statistiche non aggiornate.
Come controllare le statistiche non aggiornate
La procedura PLSQL seguente trova tutte le tabelle nello schema SCOTT che sono statistiche non aggiornate
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; /
Il seguente sql può essere utilizzato anche per scoprire inserimenti, aggiornamenti, eliminazioni
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 vuoi eseguirlo sull'intero database
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 vuoi vedere le tabelle in cui le statistiche sono vuote, possiamo usare di seguito
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; /
Ora una volta trovato l'elenco delle tabelle, puoi generare statistiche su queste tabelle.
exec dbms_stats.gather_table_stats('OWNER', 'TABLE_NAME');
Possiamo anche eseguire il comando seguente per generare statistiche su tutti gli oggetti non aggiornati nello schema
exec dbms_stats.gather_schema_stats(ownname => '<schema name>', cascade => TRUE, options => 'GATHER AUTO');
A partire da Oracle11g, la soglia di obsolescenza può essere impostata utilizzando la preferenza delle statistiche STALE_PERCENT. Questo può essere impostato a livello globale utilizzando DBMS_STATS.SET_GLOBAL_PREFS oa livello di tabella utilizzando DBMS_STATS.SET_TABLE_PREFS.
Articoli correlati
ora-38029:le statistiche degli oggetti sono bloccate
ora-20001 in Gather schema stats on 11g(FND_HISTOGRAM_COLS)
Raccolta di statistiche in Release 11i e R12
Incremental Statistics Gathering in 11g
Come fare per imposta il monitoraggio della tabella in Oracle e la relazione con STATISTICS_LEVEL