Les statistiques peuvent devenir obsolètes lorsque les données du tableau changent considérablement. Des statistiques à jour sont importantes pour générer de bons plans d'exécution
Comment Oracle décide si les statistiques sont devenues obsolètes
Les statistiques sont considérées comme obsolètes lorsque #(INSERTS + UPDATES + DELETES)>=10 % de NUM_ROWS de dba_tables :
Réglage des paramètres requis pour suivre les modifications du tableau
Avant Oracle 10g, la collecte automatisée de statistiques pour les objets devenus obsolètes était contrôlée par la définition de l'indicateur MONITORING sur la table.
Selon l'indicateur MONITORING, le travail GATHER_STATS_JOB collectait "GATHER EMPTY" et "GATHER STALE" sur les objets marqués.
Dans la version 10g, les mots clés MONITORING et NOMONITORING sont obsolètes et seront ignorés. La fonction de surveillance des tables est désormais contrôlée par le paramètre STATISTICS_LEVEL.
Lorsque STATISTICS_LEVEL est défini sur BASIC, la surveillance est désactivée sur la table.
Lorsque STATISTICS_LEVEL est défini sur TYPICAL, la surveillance est activée.
Par défaut, STATISTICS_LEVEL est défini sur TYPICAL et la surveillance des tables est activée. Il est fortement recommandé de définir STATISTICS_LEVEL sur TYPICAL dans les versions 10g et supérieures
En définissant ces paramètres, Oracle suit le nombre approximatif d'opérations INSERT, UPDATE et DELETE pour la table Oracle depuis la dernière collecte de statistiques. Ces informations sur les "modifications apportées" sont conservées dans la SGA et périodiquement (environ toutes les 15 minutes) le SMON vide les données dans les tables du dictionnaire de données. Vous pouvez vider manuellement les informations en appelant dbms_stats.FLUSH_DATABASE_MONITORING_INFO(). Les informations du dictionnaire de données sont rendues visibles à travers les vues :DBA_TAB_MODIFICATIONS, ALL_TAB_MODIFICATIONS et USER_TAB_MODIFICATIONS.
Oracle utilise ces vues pour identifier les tables dont les statistiques sont obsolètes.
Chaque fois qu'il y a 10 % de changement dans les données d'une table, Oracle considère ses statistiques comme obsolètes.
Comment vérifier les statistiques obsolètes
La procédure PLSQL ci-dessous trouve toutes les tables du schéma SCOTT qui sont des statistiques obsolètes
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; /
Le sql ci-dessous peut également être utilisé pour découvrir les insertions, les mises à jour, les suppressions
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 /
Si vous voulez exécuter ceci sur toute la base de données
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; /
Si vous voulez voir les tableaux où les statistiques sont vides, nous pouvons utiliser ci-dessous
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; /
Maintenant, une fois que vous avez trouvé la liste des tables, vous pouvez générer des statistiques sur ces tables.
exec dbms_stats.gather_table_stats('OWNER', 'TABLE_NAME');
Nous pouvons également exécuter la commande ci-dessous pour générer des statistiques sur tous les objets obsolètes du schéma
exec dbms_stats.gather_schema_stats(ownname => '<schema name>', cascade => TRUE, options => 'GATHER AUTO');
À partir d'Oracle11g, le seuil d'obsolescence peut être défini à l'aide de la préférence statistique STALE_PERCENT. Cela peut être défini globalement à l'aide de DBMS_STATS.SET_GLOBAL_PREFS ou au niveau de la table à l'aide de DBMS_STATS.SET_TABLE_PREFS.
Articles connexes
ora-38029 :les statistiques d'objet sont verrouillées
ora-20001 dans Gather schema stats on 11g(FND_HISTOGRAM_COLS)
Gathering Statistics in Release 11i and R12
Incremental Statistics Gathering in 11g
How to définir la surveillance des tables dans Oracle et la relation avec STATISTICS_LEVEL