Performance
Odkąd baza Oracle opiera swoją potęgę wydajnościową na optymalizatorze kosztowym, poprawne zbieranie i przechowywanie statystyk stało się jednym z głównych obszarów tematu strojenia bazy danych. Przyjrzyjmy się niektórym nowym cechom statystyk, które dostarcza nam baza Oracle 11g.
„Wiszące” statystyki
baza Oracle 11g daje nam opcję wyboru, czy zebrane statystyki zostaną opublikowane po zebraniu, czy otrzymają status „wiszącej” statystyki. Żeby określić, czy statystyki zostaną opublikowane bezpośrednio po zebraniu, czy też otrzymają status „wiszących”, możemy użyć funkcji GET_PREFS('PUBLISH') z pakietu DBMS_STATS. Jeżeli funkcja zwróci wartość TRUE, będzie to oznaczało, że statystyki zostaną opublikowane bezpośrednio po zebraniu. Aby zmienić ten parametr możemy skorzystać z funkcji SET_SCHEMA_PREFS (lub SET_TABLE_PREFS gdy chcemy wskazać konkretną tabelę), również znajdującej się w pakiecie DBMS_STATS. Gdy statystyki zostaną zebrane jako „wiszące”, możemy podejrzeć wygenerowane wartości w odpowiednich tabelach słownika danych: USER_TAB_PENDING_STATISTICS, USER_COL_PENDING_STATISTICS, USER_IND_PENDING_STATISTICS. Następnie w zależności od tego, czy uzyskamy zadowalający nas efekt, możemy statystyki opublikować (DBMS_STATS.PUBLISH_PENDING_STATS), bądź skasować (DBMS_STATS_DELETE_PEDING_STATS).
Przykład:
2 from dual;
DBMS_STATS.GET_PREFS('PUBLISH','HR','EMPLOYEES2')
--------------------------------------------------------------------------------
TRUE
SQL> begin
2 dbms_stats.set_table_prefs('HR','EMPLOYEES2','PUBLISH','FALSE');
3 end;
4 /
Procedura PL/SQL zostala zakonczona pomyslnie.
SQL> delete employees2;
110 wierszy zostalo usunietych.
SQL> commit;
Zatwierdzanie zostalo ukonczone.
SQL> begin
2 dbms_stats.gather_table_stats('HR','EMPLOYEES2');
3 end;
4 /
Procedura PL/SQL zostala zakonczona pomyslnie.
SQL> select 'OPUBPLIKOWANE :' || num_rows as pub
2 from user_tables
3 where table_name='EMPLOYEES2';
PUB
-------------------------------------------------------
OPUBPLIKOWANE :110
SQL> select 'WISZACE :' || num_rows as pend
2 from user_tab_pending_stats
3 where table_name='EMPLOYEES2';
PEND
-------------------------------------------------
WISZACE :0
SQL> begin
2 dbms_stats.publish_pending_stats('HR','EMPLOYEES2');
3 end;
4 /
Procedura PL/SQL zostala zakonczona pomyslnie.
SQL> select 'OPUBPLIKOWANE :' || num_rows as pend
2 from user_tables
3 where table_name='EMPLOYEES2';
PEND
-------------------------------------------------------
OPUBPLIKOWANE :0
Statystyki, które nie są opublikowane, nie mają wpływu na zmianę planu wykonania zapytania, wyjątkiem jest sytuacja, gdy wartość parametru optimizer_use_pending_statistics jest ustawiona na TRUE.
Statystyki wielokolumnowe i oparte na funkcjach
Oracle 11g przedstawia nowe możliwości w generowaniu histogramów. Począwszy od tej wersji bazy danych mamy możliwość zbierania statystyk opartych na grupie kolumn oraz na funkcjach. Dzięki tej możliwości otwierają się zupełnie nowe możliwości wpływania na optymalizator kosztowy w celu wygenerowania najbardziej właściwego planu wykonania zapytania. Aby skorzystać z możliwości generowania statystyk wielokolumnowych należy uprzednio stworzyć grupę kolumn, do której będziemy się odwoływać.
Przykład:
2 v_name varchar2(30);
3 begin
4 v_name :=
dbms_stats.create_extended_stats(null,'EMPLOYEES','(DEPARTMENT_ID,JOB_ID)');
5 end;
6 /
Procedura PL/SQL zostala zakonczona pomyslnie.
SQL> begin
2 dbms_stats.gather_table_stats(null,'EMPLOYEES', method_opt=>'for all columns size auto for
columns (DEPARTMENT_ID,JOB_ID)');
3 end;
4 /
Procedura PL/SQL zostala zakonczona pomyslnie.
SQL> begin
2 dbms_stats.gather_table_stats(null,'EMPLOYEES', method_opt=>'for all columns size auto for
columns (lower(FIRST_NAME))');
3 end;
4 /
SQL> select extension_name, extension
2 from user_stat_extensions
3 where table_name='EMPLOYEES';
EXTENSION_NAME EXTENSION
------------------------------ ------------------------------------------------------------
SYS_STUCCK0PNI_XUVBAGRNRRUF29S ("DEPARTMENT_ID","JOB_ID")
SYS_STUKTFUBS35V1$LRO53L2Z$F8R (LOWER("FIRST_NAME"))
Jakkolwiek funkcjonalność wydaje się być ciekawa oraz obiecująca, przeprowadzone testy wskazują, że mechanizm jest jeszcze niestabilny a zachowanie optymalizatora trudne do przewidzenia.
Bind-Aware Peeking
Do tej pory używanie zmiennych wiązanych mogło nieść ze sobą ryzyko zmniejszenia wydajności zapytań, gdy w kolumnach znajdowały się dane o nierównomiernym rozkładzie, nadające się do zakładania histogramów. Oracle 11g proponuje nam rozwiązanie mające uwolnić nas od problemu wybierania, kiedy używać zmiennych wiązanych a kiedy jednak lepiej jest użyć literałów. Dzięki nowemu mechanizmowi Bind-Aware Peeking, SQL przy pierwszym wykonaniu przejdzie normalne, twarde parsowanie. Następne wykonanie spowoduje znalezienie zbuforowanego planu wykonania zapytania, unikając twardego parsowania. Po wykonaniu SQL, jego statystyki dotyczące wykonania zostaną porównane ze statystykami z poprzednich wykonań. Jeżeli Oracle zauważy, że porównanie wypada na niekorzyść, oznaczy nasz kursor jako bind-aware. Dzięki temu przy kolejnych wykonaniach będzie sprawdzana selektywność predykatów i, jeśli trzeba, wygenerowany nowy plan wykonania zapytania. Efektem takiego działania jest powstanie kilku różnych planów wykonania zapytania dla tego samego kursora, zawierającego zmienne wiązane. Odpowiedni plan będzie wybierany na podstawie wartości przypisanych do zmiennych wiązanych.