Jedenaście dni temu pisałem na blogu o tym, jak Adaptive Dynamic Stats zużywa zasoby w moich produkcyjnych bazach danych RAC.
Po ugaszeniu tego pożaru przystąpiłem do zbadania niektórych słabo wydajnych zapytań zgłaszanych przez naszych pracowników ds. kontroli jakości w testowych i innych nieprodukcyjnych bazach danych. Zrobiłem tak, jak zrobiłby każdy dobry administrator bazy danych Oracle. Zebrałem wywołanie procedury składowanej, które powielało problem. W mojej sesji uruchomiłem śledzenie SQL i uruchomiłem procedurę składowaną. Ukończenie zajęło 50 sekund, podczas gdy uaktualnienie z 11.2.0.4 do 12.1.0.2 zajmowało 5 sekund lub mniej. Ta procedura składowana zawiera pewną liczbę instrukcji SQL, a ślad SQL wydaje się logicznym miejscem do rozpoczęcia. Musiałem wiedzieć, która instrukcja SQL w procedurze powoduje problemy.
Uruchomiłem plik śledzenia SQL przez TKPROF i byłem zaskoczony wynikami. Wydawało się, że instrukcje SQL w procedurze składowanej wykonują się dość szybko. Ale powitało mnie wiele stwierdzeń podobnych do następujących:
SELECT /* DS_SVC */ /*+ dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) no_parallel */ SUM(C1) FROM (SELECT /*+ qb_name("innerQuery") INDEX_FFS( "XXX" "INDEX_NAME") */ 1 AS C1 FROM "OWNER"."TABLE_NAME" SAMPLE BLOCK(71.048, 8) SEED(1) "XXX") innerQuery
To jest dynamiczne próbkowanie w pracy. Patrząc na wszystkie instrukcje dynamicznego próbkowania wykonywane w moim pliku śledzenia, udało mi się ustalić, że stanowiły one 45 sekund całego czasu działania! Ups!
Dynamic Sampling ma mi w tym pomóc. Czas poświęcony na uzyskanie niektórych przykładowych statystyk powinien być znacznie mniejszy niż ilość czasu zaoszczędzona przez wykonanie instrukcji SQL z lepszymi statystykami. Jeśli tak się nie stanie, wydajność instrukcji SQL może ucierpieć, tak jak w moim przypadku.
Zauważyłem, że jedną rzeczą, która moim zdaniem była interesująca, było to, że te zapytania dynamicznego próbkowania były wykonywane raz dla każdej tabeli i raz dla każdego z jej indeksów. Jedna z tabel biorących udział w moim zapytaniu ma 7 indeksów, więc dla tej jednej tabeli miałem 8 zapytań z dynamicznym próbkowaniem!
W moim poście na blogu 11 dni temu ustawiłem parametroptimer_dynamic_sampling na 0, co uniemożliwia wykonanie tych zapytań. Nie wprowadziłem jeszcze tej zmiany do naszego środowiska testowego, więc musiałem to zrobić. Jak tylko to zrobiłem, wydajność zapytań wróciła do normy. Domyślna wartość tego parametru dla mojej bazy danych to 2. Wartość domyślna może się różnić w zależności od wartości ustawieniaOptimizer_features_enable. Według tego wpisu na blogu wartość 2 oznacza, że dynamiczne próbkowanie zostanie uruchomione, gdy co najmniej jedna z tabel nie zawiera statystyk. Ale szczerze mówiąc, samplowanie dynamiczne nie daje mi żadnych korzyści, a jedynie szkodzi. Więc na razie zostawię to w całości.