Statystyki mogą stać się nieaktualne, gdy dane w tabeli zmienią się znacząco.Aktualne statystyki są ważne, aby generować dobre plany wykonania
Jak Oracle decyduje, czy statystyki się zestarzały
Statystyki są uważane za nieaktualne, gdy #(INSERTS + UPDATES + DELETE)>=10% z NUM_ROWS z dba_tables:
Ustawienie parametrów wymagane do śledzenia zmian w tabeli
Przed wersją Oracle 10g automatyczne zbieranie statystyk dla obiektów, które stały się przestarzałe, było kontrolowane przez ustawienie flagi MONITORING w tabeli.
W zależności od flagi MONITORING zadanie GATHER_STATS_JOB zbierało wartości „GATHER EMPTY” i „GATHER STALE” na oznaczonych obiektach.
W 10g słowa kluczowe MONITORING i NOMONITORING są przestarzałe i będą ignorowane. Funkcja monitorowania tabeli jest teraz kontrolowana przez parametr STATISTICS_LEVEL.
Gdy STATISTICS_LEVEL jest ustawione na BASIC, monitorowanie jest wyłączone w tabeli.
Gdy STATISTICS_LEVEL jest ustawione na TYPICAL, monitorowanie jest włączone.
Domyślnie STATISTICS_LEVEL jest ustawione na TYPICAL i monitorowanie tabel jest włączone. Zdecydowanie zaleca się ustawienie parametru STATISTICS_LEVEL na TYPICAL dla 10g i wyższych
Ustawiając ten parametr, Oracle śledzi przybliżoną liczbę operacji INSERT, UPDATE i DELETE dla tabeli Oracle od czasu ostatniego zebrania statystyk. Ta informacja o „wprowadzonych zmianach” jest przechowywana w SGA i okresowo (co około 15 minut) SMON opróżnia dane do tabel słownika danych. Informacje można usunąć ręcznie, wywołując funkcję dbms_stats.FLUSH_DATABASE_MONITORING_INFO(). Informacje ze słownika danych są widoczne w widokach:DBA_TAB_MODIFICATIONS, ALL_TAB_MODIFICATIONS i USER_TAB_MODIFICATIONS.
Oracle używa tych widoków do identyfikowania tabel, które mają nieaktualne statystyki.
Za każdym razem, gdy w tabeli występuje 10% zmiana danych, Oracle uważa, że jej statystyki są nieaktualne.
Jak sprawdzić statystyki nieaktualności
Poniższa procedura PLSQL pozwala znaleźć wszystkie tabele w schemacie SCOTT, które są przestarzałe statystyki
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; /
Poniższy sql można również wykorzystać do wyszukiwania wstawiania, aktualizacji, usuwania
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 /
Jeśli chcesz uruchomić to na całej bazie danych
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; /
Jeśli chcesz zobaczyć tabele, w których statystyki są puste, możemy użyć poniżej
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; /
Teraz po znalezieniu listy tabel możesz wygenerować statystyki dotyczące tych tabel.
exec dbms_stats.gather_table_stats('OWNER', 'TABLE_NAME');
Możemy również uruchomić poniższe polecenie, aby wygenerować statystyki dotyczące wszystkich przestarzałych obiektów w schemacie
exec dbms_stats.gather_schema_stats(ownname => '<schema name>', cascade => TRUE, options => 'GATHER AUTO');
Począwszy od Oracle11g, próg nieaktualności można ustawić za pomocą preferencji statystyk STALE_PERCENT. Można to ustawić globalnie za pomocą DBMS_STATS.SET_GLOBAL_PREFS lub na poziomie tabeli za pomocą DBMS_STATS.SET_TABLE_PREFS.
Powiązane artykuły
ora-38029:statystyki obiektów są zablokowane
ora-20001 w Gather schema stats on 11g(FND_HISTOGRAM_COLS)
Gathering Statistics w wersji 11i i R12
Przyrostowe zbieranie statystyk w 11g
Jak to zrobić ustaw monitorowanie tabeli w Oracle i relacji z STATISTICS_LEVEL