Статистиката може да стане остаряла, когато данните в таблицата се променят значително. Актуалните статистически данни са важни за генериране на добри планове за изпълнение
Как Oracle решава дали статистиката е остаряла
Статистическите данни се считат за остарели, когато #(INSERTS + UPDATES + DELETES)>=10% от NUM_ROWS от dba_tables:
Необходима е настройка на параметър за проследяване на промените в таблицата
Преди Oracle 10g, автоматизираното събиране на статистически данни за обекти, които са остарели, се контролираше от настройката на флага MONITORING на таблицата.
В зависимост от флага MONITORING, заданието GATHER_STATS_JOB събираше „GATHER EMPTY“ и „GATHER STALE“ върху маркираните обекти.
В 10g ключовите думи MONITORING и NOMONITORING са отхвърлени и ще бъдат игнорирани. Функцията за наблюдение на таблици вече се контролира от параметъра STATISTICS_LEVEL.
Когато STATISTICS_LEVEL е зададен на BASIC, наблюдението е деактивирано на таблицата.
Когато STATISTICS_LEVEL е зададено на TYPICAL, тогава наблюдението е активирано.
По подразбиране STATISTICS_LEVEL е зададено на TYPICAL и наблюдението на таблиците е разрешено. Силно препоръчително е да зададете STATISTICS_LEVEL на TYPICAL в 10 g и повече
Чрез задаването на този параметър Oracle проследява приблизителния брой операции INSERT, UPDATE и DELETE за таблицата на Oracle от последния път, когато са били събрани статистически данни. Тази информация за „извършените промени“ се поддържа в SGA и периодично (на всеки 15 минути) SMON изтрива данните в таблиците на речника с данни. Можете ръчно да изчистите информацията, като извикате dbms_stats.FLUSH_DATABASE_MONITORING_INFO(). Информацията от речника на данните се прави видима чрез изгледите:DBA_TAB_MODIFICATIONS, ALL_TAB_MODIFICATIONS и USER_TAB_MODIFICATIONS.
Oracle използва тези изгледи, за да идентифицира таблици, които имат остарели статистически данни.
Всеки път, когато има 10% промяна в данните в таблица, Oracle счита нейните статистически данни за остарели.
Как да проверите застояли статистически данни
PLSQL процедурата по-долу намира всички таблици в схемата на SCOTT, която е остаряла статистика
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; /
По-долу sql може да се използва и за намиране на вмъкване, актуализация, изтриване
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 /
Ако искате да стартирате това върху цялата база данни
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; /
Ако искате да видите таблиците, където статистиката е празна, можем да използваме по-долу
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; /
Сега, след като намерите списъка с таблици, можете да генерирате статистически данни за тези таблици.
exec dbms_stats.gather_table_stats('OWNER', 'TABLE_NAME');
Можем също да изпълним командата по-долу, за да генерираме статистика за всички остарели обекти в схемата
exec dbms_stats.gather_schema_stats(ownname => '<schema name>', cascade => TRUE, options => 'GATHER AUTO');
Започвайки с Oracle11g, прагът на застояване може да бъде зададен с помощта на предпочитанието за статистически данни STALE_PERCENT. Това може да бъде зададено глобално с помощта на DBMS_STATS.SET_GLOBAL_PREFS или на ниво таблица с помощта на DBMS_STATS.SET_TABLE_PREFS.
Сродни статии
ora-38029:статистическите данни за обекта са заключени
ora-20001 в Събиране на статистически данни за схемата на 11g(FND_HISTOGRAM_COLS)
Събиране на статистически данни в Версия 11i и R12
Постепенно събиране на статистически данни в 11g до
задайте наблюдение на таблици в Oracle и връзка със STATISTICS_LEVEL