PL/SQL Hierarchical Profiler jako zaawansowana metoda strojenia wydajności aplikacji

Podobne dokumenty
Usługi analityczne budowa kostki analitycznej Część pierwsza.

Pakiety podprogramów Dynamiczny SQL

Plan. Wprowadzenie. Co to jest APEX? Wprowadzenie. Administracja obszarem roboczym

Bazy danych. Zenon Gniazdowski WWSI, ITE Andrzej Ptasznik WWSI

Projektowanie baz danych za pomocą narzędzi CASE

PHP: bazy danych, SQL, AJAX i JSON

Jak ustawić cele kampanii?

GNU GProf i GCov. przygotował: Krzysztof Jurczuk Politechnika Białostocka Wydział Informatyki Katedra Oprogramowania ul. Wiejska 45A Białystok

NETBEANS PROFILER TOMASZ ŁUKASZUK

Wdrożenie modułu płatności eservice. dla systemu Magento

System. Instalacja bazy danych MySQL. Autor : Piotr Zielonka tel Piotrków Tryb., sierpień 2018r.

Język PL/SQL Procedury i funkcje składowane

Instalacja SQL Server Express. Logowanie na stronie Microsoftu

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Monitoring procesów z wykorzystaniem systemu ADONIS

DECLARE VARIABLE zmienna1 typ danych; BEGIN

Wdrożenie modułu płatności eservice. dla systemu oscommerce 2.3.x

Język PL/SQL Pakiety podprogramów

Wdrożenie modułu płatności eservice. dla systemu Zen Cart

REFERAT PRACY DYPLOMOWEJ Temat pracy: Projekt i realizacja serwisu ogłoszeń z inteligentną wyszukiwarką

Szkolenie: Testowanie wydajności (Performance Testing)

Diagram wdrożenia. Rys. 5.1 Diagram wdrożenia.

Aplikacje WWW - laboratorium

Zaawansowane aplikacje internetowe

KOMPUTEROWY SYSTEM WSPOMAGANIA OBSŁUGI JEDNOSTEK SŁUŻBY ZDROWIA KS-SOMED

Szkolenie autoryzowane. MS 6232 Wdrażanie bazy danych Microsoft SQL Server 2008 R2

Wdrożenie modułu płatności eservice. dla systemu Gekosale 1.4

SQL w 24 godziny / Ryan Stephens, Arie D. Jones, Ron Plew. Warszawa, cop Spis treści

Grzegorz Ruciński. Warszawska Wyższa Szkoła Informatyki Promotor dr inż. Paweł Figat

Projekt ZSWS. Instrukcja uŝytkowania narzędzia SAP Business Explorer Analyzer. 1 Uruchamianie programu i raportu. Tytuł: Strona: 1 z 31

REFERAT PRACY DYPLOMOWEJ

Instrukcja instalacji i obsługi programu Szpieg 3

Oracle PL/SQL. Paweł Rajba.

Problemy optymalizacji, rozbudowy i integracji systemu Edu wspomagającego e-nauczanie i e-uczenie się w PJWSTK

Uruchomienie nowego kontekstu aplikacji

Optimed24 Przenoszenie bazy danych PostrgreSQL

Monitoring procesów z wykorzystaniem systemu ADONIS. Krok po kroku

Oracle Designer. Oracle Designer jest jednym z głównych komponentów pakietu Oracle Developer Suite. Oracle Designer wspiera :

System magazynowy małego sklepu.

Rozdział 17. Zarządzanie współbieżnością zadania

D:\DYDAKTYKA\ZAI_BIS\_Ćwiczenia_wzorce\04\04_poprawiony.doc 2009-lis-23, 17:44

VinCent v.1.40 zmiany w programie

Migracja XL Business Intelligence do wersji

Tworzenie raportów XML Publisher przy użyciu Data Templates

Modelowanie hierarchicznych struktur w relacyjnych bazach danych

Spis treści. Przedmowa

Aplikacje WWW - laboratorium

Tworzenie aplikacji bazodanowych

Instrukcja obsługi Systemu monitorowania pomocy publicznej DEMINIMIS (v. 2.00)

Procedury i funkcje składowane

Blaski i cienie wyzwalaczy w relacyjnych bazach danych. Mgr inż. Andrzej Ptasznik

Gerard Frankowski, Zespół Bezpieczeństwa PCSS. Nowoczesne technologie bliżej nas Poznań,

XQTav - reprezentacja diagramów przepływu prac w formacie SCUFL przy pomocy XQuery

Win Admin Monitor Instrukcja Obsługi

Usługa: Testowanie wydajności oprogramowania

FUNKCJONALNOŚ C PORTAL B2B KAMELEON.ŚQL

Oracle11g: Programowanie w PL/SQL

Zarządzanie kontami użytkowników w i uprawnieniami

Nie przegrzewaj mózgu wrzuć dane do bazy!

enova Systemowe Narzędzia Projektowe

15. Funkcje i procedury składowane PL/SQL

Oracle10g: Programowanie w PL/SQL

Migracja Business Intelligence do wersji 11.0

Oracle PL/SQL. Paweł Rajba.

Wstęp. Opis ten dotyczy wydziałów orzeczniczych.

Tworzenie bazy danych w środowisku OpenOffice.org Base tabela, formularz, kwerenda, raport

!!!!!!!!!!! PORTFOLIO: Analiza zachowań użytkowników serwisów internetowych. Autorzy: Marek Zachara

S P I S T R E Ś C I. Instrukcja obsługi

System Zarządzania Dystrybucją

Cele. Definiowanie wyzwalaczy

Plan. Formularz i jego typy. Tworzenie formularza. Co to jest formularz? Typy formularzy Tworzenie prostego formularza Budowa prostego formularza

Currenda EPO Instrukcja Konfiguracji. Wersja dokumentu: 1.3

Język PL/SQL. Rozdział 5. Pakiety podprogramów. Dynamiczny SQL

Instrukcja migracji danych z bazy Derby do bazy Oracle

Bazy danych. Wykład IV SQL - wprowadzenie. Copyrights by Arkadiusz Rzucidło 1

Pracownia internetowa w szkole ZASTOSOWANIA

Zapewnij sukces swym projektom

Instrukcja aktualizacji programu Integra 7

Aplikacje webowe w obliczu ataków internetowych na przykładzie CodeIgniter Framework

Uruchamianie bazy PostgreSQL

Pakiety są logicznymi zbiorami obiektów takich jak podprogramy, typy, zmienne, kursory, wyjątki.

Procedury składowane. Funkcje vs. procedury Funkcja. Procedura. zazwyczaj ma parametry tylko typu IN; można wywoływać z poziomu

Paweł Cieśla. Dokumentacja projektu

Oracle Application Express -

Przypadki testowe. Spis treści. Plan testów. From Sęp. Wstęp. 2 Plan testów

Spis treści MONITOR PRACY... 4

SAS Institute Technical Support

Aplikacje WWW - laboratorium

Instalacja i opis podstawowych funkcji programu Dev-C++

Przewodnik instalacji i rozpoczynania pracy. Dla DataPage+ 2013

Procedury pozwalające na uproszczenie procesu. projektowania. ZW3D CAD/CAM Biała księga

Przewodnik użytkownika (instrukcja) AutoMagicTest

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Szpieg 2.0 Instrukcja użytkownika

Program szkolenia: Continuous Integration i Git

Aproksymacja funkcji a regresja symboliczna

e-audytor v.3.x INSTRUKCJA INSTALACJI I URUCHOMIENIA SYSTEMU

7. Formularze master-detail

Migracja Business Intelligence do wersji

Transkrypt:

XVI Konferencja PLOUG Kościelisko Październik 2010 PL/SQL Hierarchical Profiler jako zaawansowana metoda strojenia wydajności aplikacji Piotr Węsław Roche Polska Sp. z o.o. piotr.weslaw@roche.com Abstrakt. PL/SQL Hierarchical Profiler jest nowym narzędziem dostarczanym z bazą danych Oracle 11g. Służy ono do diagnozowania problemów wydajnościowych w kodzie PL/SQL owym, które przy zastosowaniu dotychczasowych narzędzi były trudne lub wręcz niemożliwe do wykrycia. Jego użycie jest bardzo proste i sprowadza się do włączenia narzędzia, uruchomienia analizowanego kodu oraz wygenerowania zbioru raportów. Ilość informacji dostarczonych w tych raportach jest jednak tak duża, ze ich interpretacja jest kłopotliwa bez wcześniejszego zrozumienia modelu koncepcyjnego. Niniejsze opracowanie koncentruje się na przedstawieniu tego modelu wraz z kilkoma przykładami oraz zaprezentowaniu metody pozwalającej ocenić przydatność użycia PL/SQL Hierarchical Profilera w konkretnych sytuacjach. Informacja o autorze. Piotr Węsław jest aktualnie pracownikiem farmaceutycznej firmy Roche Polska Sp. z o.o. Jeszcze podczas studiów na Wydziale Elektroniki i Technik Informacyjnych Politechniki Warszawskiej zajmował się zagadnieniami związanymi z bazami danych ze szczególnym uwzględnieniem technologii Oracle. Od początku kariery zawodowej skupia się na tematyce dotyczącej współbieżności i strojenia wydajności dużych baz danych Oracle, zarówno hurtowni danych, jak i systemów transakcyjnych.

PL/SQL Hierarchical Profiler jako zaawansowana metoda strojenia wydajności aplikacji 41 1. Wstęp Strojenie wydajności aplikacji jest zagadnieniem złożonym, często opisywanym w publikacjach oraz omawianym podczas konferencjach informatycznych. Z biznesowego punktu widzenia tematyka ta z reguły sprowadza się do jednego założenia określone zadania systemu informatycznego powinny wykonywać się w określonym z góry przedziale czasowym. Jeśli ten warunek nie jest spełniony, wtedy osoby zajmujące się projektowaniem lub utrzymaniem aplikacji zaczynają pracować się strojeniem wydajności. Z technicznego punktu widzenia, problem ten można analizować na wielu różnych płaszczyznach. Często analiza problemu zaczyna się od obszaru, którym zajmuje się konkretna osoba przypisana do poprawy wydajności aplikacji. Może to być próba optymalizacji samej aplikacji lub jednego z wielu komponentów, na których jest ona uruchomiona, takich jak: serwer aplikacji, baza danych czy systemy operacyjne. Niestety takie podejście może skutkować sytuacją, w której wysiłek podejmowany jest w nieoptymalnym miejscu. Na przykład, w sytuacji gdy większość czasu aplikacja spędza na wykonywaniu zapytań SQL, nie ma sensu optymalizacji serwera aplikacyjnego. Najlepsze rezultaty przynosi podejście, w którym wysiłek koncentrowany jest w tym miejscu, w którym potencjalnie może przynieść największe rezultaty. Jednym z dylematów, przed którym mogą stanąć osoby zajmujące się strojeniem wydajności baz danych, dotyczy oceny czy lepsze rezultaty przyniesie optymalizacja zapytań SQL czy kodu napisanego w PL/SQL u. W bazie danych Oracle dostępnych jest kilka narzędzie, które pomagają podjąć tą decyzję. Można podzielić je na dwie grupy: narzędzia śledzące wykonywanie zapytań SQL lub poleceń PL/SQL (np. SQL trace, DBMS_PROFILER) narzędzia śledzące sposób wykonywania programów, łącznie z pełną historia wywołań poszczególnych podprogramów (np. PL/SQL Hierarchical Profiler) PL/SQL Hierarchical Profiler może być pomocy zarówno w podjęciu decyzji o tym, czy optymalizacja powinna dotyczyć programów PL/SQL owych, jak i sposobu analizy tego kodu. Jego przydatność może być jeszcze bardziej widoczna w sytuacjach, w których osoba zajmująca się strojeniem wydajności nie jest autorem rozwiązania, a jednocześnie jest ono na tyle skomplikowane, że analiza kodu źródłowego jest niemożliwa. W praktyce jedyną rzeczą jaką można zrobić jest uruchomienie aplikacji i obserwacja tego co dzieje się w bazie danych. 2. Profilowanie oparte o śledzenie poleceń Tradycyjne podejście do optymalizacji kodu aplikacji na poziomie bazy danych opiera się na śledzeniu zapytań SQL lub poleceń PL/SQL. Rozwiązania ułatwiające takie profilowanie dostępne są już od dłuższego czasu poprzez takie narzędzia jak: SQL trace (np. polecenie ALTER SESSION SET sql_trace = TRUE;) oraz tkprof pakiet DBMS_TRACE pakiet DBMS_PROFILER Podczas wykonywania analizowanego kodu, narzędzia te rejestrują ilości wykonań poszczególnych zapytań SQL owych lub poleceń PL/SQL oraz związany z tym czas. W sytuacji, w której słaba wydajność aplikacji spowodowana jest konkretnym zapytaniem lub poleceniem, podejście te umożliwia w łatwy sposób znalezienie miejsca w aplikacji, którego optymalizacja przyniesie wymierne korzyści. W tym momencie mogą pojawić się pewne trudności jeśli optyma-

42 Piotr Węsław lizacji wymaga sposób w jaki poszczególne podprogramy wewnątrz pakietu PL/SQL owego współpracują między sobą. Takie informacje nie są niestety rejestrowane podczas wykonywania kodu. W przypadku optymalizacji zapytań SQL zasadniczo ten problem nie występuje, ponieważ dokładny sposób realizacji zapytań dostępny jest w planach ich wykonań. Narzędzia używane do profilowania opartego o śledzenie poleceń mają bogate możliwości konfiguracji (np. rejestrowanie wartości zmiennych wiązanych). Jednak u podstaw zasady ich działania leżą założenia, które powodują, że następujące informacje nie są dostępne: wywołania poszczególnych podprogramów wewnątrz pakietu PL/SQL owego. Przykładowo, jeśli pakiet składa się z 10 funkcji wywołujących się wzajemnie, informacja o tym fakcie jest niedostępna. W praktyce poziom zagnieżdżenia może być dużo większy i zrozumienie kolejności wywołań na podstawie zadanych wartości parametrów wejściowych oraz czytania kodu źródłowego, może być niemożliwe. ilość czasu spędzonego wewnątrz samej procedury/funkcji (bez uwzględniania wywoływanych podprogramów) versus całkowity czas spędzony na sama procedurę/funkcję łącznie ze wszystkimi wywoływanymi podprogramami. Powyższe informację są doskonałym punktem startowym do pracy nad optymalizacją kodu PL/SQL owego. Profilowanie hierarchiczne oraz rozwiązania dostępne w bazie Oracle od wersji 11g umożliwiają ich uzyskanie. 3. Model koncepcyjny profilowania hierarchicznego Podstawowa różnica między profilowaniem opartym o śledzenie zapytań a profilowaniem hierarchicznym polega na tym, ze w drugim przypadku zapamiętywany jest kontekst wywołania. PL/SQL Hierarchical Profiler obserwuje w jaki sposób i w jakiej kolejności wywoływane są kolejne podprogramy. Oczywiście dla danego podprogramu jego zachowanie (a co za tym idzie wywoływanie kolejnych podprogramów) może być różne w zależności wartości parametrów wejściowych. Profilowanie hierarchiczne bazuje na konkretnym eksperymencie (tj. uruchamiamy procedurę z zadanymi parametrami wejściowymi), więc można spodziewać się, że zmiana parametrów wejściowych spowoduje zmianę wyników. Profilowanie hierarchiczne, w przeciwieństwie do opartego o śledzenie zapytań, dostarcza następujące informacje: pełna historia wywołań każde wywołanie podprogramu jest zapamiętywane czas spędzony pomiędzy poszczególnymi wywołaniami Na ich podstawie można obliczyć następujące statystyki związane z działaniem danego podprogramu: czas spędzony na wykonanie kodu wewnątrz podprogramu (self time) czas spędzony na oczekiwaniu aż wywoływane podprogramy skończą swoje działanie (calles time) całkowity czas spędzony na wykonanie danego podprogramu (subtree time) ilość wywołań badanego podprogramu wszystkie wywołane podprogramy oraz ich ilość z perspektywy badanego podprogramu

PL/SQL Hierarchical Profiler jako zaawansowana metoda strojenia wydajności aplikacji 43 Caller_1 Subtree = Self + Callees Caller_2 Subtree = Self + Callees... Caller_N Subtree = Self + Callees n 1 n 2 n N Number of calls = n 1 + n 2 + + n N Some_Subprogram Subtree time = Self time + Callees time c 1 c 2 c N Callee_1 Subtree = Self + Callees Callee_2 Subtree = Self + Callees... Callee_N Subtree = Self + Callees Rys. 1. Model koncepcyjny profilowania hierarchicznego Rys. 1 przedstawia model koncepcyjny profilowania hierarchicznego. W centrum analizy jest procedura o nazwie Some_Subprogram(), która wywoływana była podczas eksperymentu przez podprogramy Caller_1(), Caller_2() aż do Caller_N(). Procedura Some_Subprogram() nie wykonywała całej pracy samodzielnie korzystała z pomocy podprogramów Callee_1(), Callee_2() aż do Callee_N(). Ilość wywołań poszczególnych podprogramów oznaczona jest odpowiednio n 1, n 2 n N oraz c 1, c 2 c N. Czas spędzony na wykonywaniu danego podprogramu (subtree time) jest to suma czasu spędzonego na wykonywanie kodu zawartego w tym podprogramie dla wszystkich jego wywołań (self time) oraz czasu spędzonego na oczekiwanie aż wywoływane podprogramy wykonają swoje zadania (callees time). Subtree time = Self time + Callees time Dla każdego podprogramu wywołującego (Caller_1(), Caller_2() Caller_N()) można zaobserwowac następujące fakty: ilośc wywołań podprogramu Some_Subprogram() procentowy udział całkowitego czasu spędzonego przez podprogramu Some_Subprogram() za jaki odpowiedzialny jest dany podprogram wywołujący na podstawie ilość wywołań Dla każdego podprogramu wywoływanego (Callee_1(), Callee_2() Callee_N()) można zaobserwować następujące fakty: ile razy był wywołany przez podprogram Some_Subprogram() czas spędzony na wykonanie tego podprogramu w sytuacji gdy był on wywołany przez podprogram Some_Subprogram() W rzeczywistych systemach reprezentacja struktury w postaci przestawionej na rys.1 jest praktycznie niemożliwa, ponieważ ilość podprogramów oraz ich wzajemnych wywołań jest bardzo duża. Dlatego raporty generowane przez PL/SQL Hierarchical Profiler a reprezentowane są

44 Piotr Węsław w postaci zbioru powiązanych ze sobą tabel (np. jako strony HTML). Przykład jednej z nich zaprezentowany jest poniżej. Subtree Self Callees Calls Function time (function) time (descendants) time 52.39 1.85 50.54 421 Some_Subprogram 44.03 0.30 43.73 19 Caller_1 8.30 0.10 8.20 7 Caller_2 0.34 0.01 0.33 1 Caller_N 36.03 36.03 0 8749 Callee_1 8.99 8.99 0 6518 Callee_2 5.79 5.79 0 1464 Callee_N Tabela 1. Reprezentacja wyników pracy PL/SQL Hierarchical Profilera w postaci tabeli Na podstawie powyższych wyników eksperymentu, analizę kodu źródłowego należałoby zacząć od podprogramu Some_Subprogram(), ponieważ ma największy czas wykonania (subtree time). W dalszej kolejności byłby podprogram Callee_1() z dużym czasem przeznaczonym na wykonanie zadań własnych (self time) oraz wzajemny sposób współpracy tych dwóch podprogramów. Zrozumienie modelu koncepcyjnego przedstawionego powyżej bardzo ułatwi interpretację raportów dostarczonych przez omawiane narzędzie. 4. Przygotowanie profilera hierarchicznego do pracy PL/SQL Hierarchical Profiler dostarczany jest razem z bazą danych Oracle od wersji 11g. W początkowych wersjach nie zawierał on narzędzia, które konwertowałoby pliki śladu tworzone podczas jego pracy do zbioru stron HTML. Co prawda można było próbować analizować je samemu, ale wiązało się to ze znaczna ilość pracy. Alternatywą jest załadowanie wyników pracy PL/SQL Hierarchical Profilera do dedykowanych tabel i stworzenie własnych zapytań SQL lub wykonanie upgrade u bazy danych do wersji 11.1.0.7 i skorzystanie z możliwości automatycznego generowania stron HTML. Użycie PL/SQL Hierarchical Profilera nie wymaga instalacji ani konfiguracji. Jednak trzeba wykonań kilka czynności, aby z niego korzystać. 4.1. Utworzenie dedykowanego katalogu Na poziomie systemu operacyjnego powinien zostać utworzony katalog, do którego będą zapisywane pliki śladu oraz strony HTML. Przykładowo w systemie Windows może to być katalog d:\hprof, do którego prawa zapisu ma użytkownik przy pomocy którego została zainstalowana baza danych. Następnie w bazie danych również należy utworzyć katalog przy pomocy następującego polecenia: CREATE DIRECTORY plshprof AS d:\hprof ;

PL/SQL Hierarchical Profiler jako zaawansowana metoda strojenia wydajności aplikacji 45 4.2. Utworzenie dedykowanego użytkownika Użytkownika, który będzie przeznaczony do pracy z PL/SQL Hierarchical Profilerem można utworzyć w następujący sposób: CREATE USER hprof_user IDENTIFIED BY password; GRANT CREATE SESSION, RESOURCE TO hprof_user; GRANT EXECUTE ON DBMS_HPROF to hprof_user; GRANT READ, WRITE ON DIRECTORY plshprof TO hprof_user; 4.3. Uruchomienie PL/SQL Hierarchical Profiler a Na tym etapie można przystąpić do wykonania eksperymentu. W poniższym przykładzie procedura o nazwie MY_PROC() poddana jest profilowaniu. Kod ten powinien zostać uruchomiony przez dedykowanego użytkownika hprof_user. BEGIN END; DBMS_HPROF.START_PROFILING( plshprof, My_Run_1.trc ); MY_PROC(); DBMS_HPROF.STOP_PROFILING(); Po wykonaniu powyższego kodu w katalogu d:\hprof utworzony zostanie plik o nazwie My_Run1.trc zawierający statystyki z uruchomienia procedury MY_PROC(). 4.4. Wygenerowanie stron HTML Jeżeli profilowanie odbywa się na bazie danych w wersji 11.1.0.7 lub nowszej, plik otrzymany w poprzednim kroku można przekonwertować do zbioru stron HTML przy pomocy następującego polecenia: D:\Hprof> plshprof output My_Run_1 My_Run_1.trc Analizę procedury można rozpocząć od otwarcia pliku My_Run_1.html w przeglądarce internetowej. Na ekranie otrzymamy linki do kilkunastu raportów umożliwiających pracę nad poprawą wydajności omawianej procedury. 4.5. Tworzenie własnych raportów Jeżeli profilowanie odbywa się w bazie danych w wersji starszej niż 11.1.0.7, wtedy raporty niestety trzeba utworzyć we własnych zakresie. Oracle dostarcza jedynie zbioru tabel i narzędzia do załadowania ich danymi z eksperymentu. Tabele te można utworzyć przy pomocy następującego skryptu: $ORACLE_HOME/rdbms/admin/dbmshptab.sql Dane do tabel można załadować wykorzystując procedurę DBMS_HPROF.ANALYZE(). 5. Przykłady użycia profilera hierarchicznego Praktyczne wykorzystanie modelu koncepcyjnego profilera hierarchicznego zaprezentowane jest w poniższych przykładach. Ich istotą jest przedstawienie sposobu w jaki można znaleźć nieefektywnie działający fragment programu na podstawie eksperymentu czyli uruchomienia apli-

46 Piotr Węsław kacji. Przykłady prezentują również kilka typowych wniosków, które wypływają z analizy raportów. Z tego punktu widzenia, nie jest istotne jakie zadania wykonuje konkretny program oraz w jaki sposób można go zoptymalizować. Ważne jest, że przy pomocy PL/SQL Hierarchical Profiler a można udowodnić, że dany fragment aplikacji działa nieefektywnie oraz podać potencjalne powody takiego zachowania. W rzeczywistości poprawa wydajności często może wiązać się ze zmiana projektu całego rozwiązania. 5.1. Przykład 1 strojenie wydajności zapytań SQL czy kodu PL/SQL Celem pierwszego przykładu jest ilustracja sposobu znalezienia odpowiedzi na pytanie dotyczące rodzaju optymalizacji jaki przyniesie największe korzyści: optymalizacja zapytań SQL optymalizacja kodu PL/SQL. Po wykonaniu eksperymentu i wygenerowaniu raportów narzędziem plshprof można przystąpić do ich analizy. Trzy z nich ma nazwę zaczynającą się od Namespace Elapsed Time i różnią się jedynie sposobem sortowania. W tym kontekście namespace może przyjmować jedynie dwie wartości: PLSQL dotyczy wykonywania poleceń PL/SQL SQL dotyczy wykonywania zapytań SQL Na rys. 2 przedstawiony jest fragment takiego raportu. Na jego podstawie można stwierdzić, że 90.3% czasu przeznaczone było na wykonywanie zapytań SQL, a jedynie 9.7% na kod PL/SQL. Jest to dowód na to, że optymalizacja w tym wypadku powinna dotyczyć zapytań SQL. Podczas pracy nad rzeczywistymi systemami dostępność takiej informacji pozwala od razu skoncentrować wysiłek zespołu we właściwym miejscu. Rys. 2. Fragment raportu Namespace Elapsed Time 5.2. Przykład 2 identyfikacja niewydajnego podprogramu Celem drugiego przykładu jest ilustracja sposobu znalezienia procedury, w której powinien zostać zoptymalizowany kod PL/SQL. Struktura wywołań programu użytego do eksperymentu przedstawiona jest na rys. 3. Nie jest ona niezbędna do analizy raportów otrzymanych z PL/SQL Hierarchical Profilera, ale ułatwi ich zrozumienie. W tym przypadku program główny uruchomiony jest za pomoca procedury Main(), która wywołuje procedury P1(), P2(), P3(), P4() oraz P5(). Procedury P2(), P3() oraz P4() korzystają z podprogramu pomocniczego Helper(). Ilość i kolejność wywołań podprogramów nie jest przedstawiona na rysunku.

PL/SQL Hierarchical Profiler jako zaawansowana metoda strojenia wydajności aplikacji 47 Main P1 P2 P3 P4 P5 Helper Rys. 3. Struktura wywołań programu użytego w przykładzie 2 Na podstawie raportu Function Elapsed Time, Data sorted by Total Function Elapsed Time otrzymanego po wykonaniu eksperymentu, stworzona została tabela 2. Zawiera ona dane dotyczące całkowitego czasu wykonania podprogramu (subtree time), czasu spędzonego wewnątrz podprogramu (self time) oraz czas spędzonego na oczekiwaniu aż wywołane podprogramy wykonają swoje zadania (callees time). Subtree Self (function) Callees (descendants) time [s] time [s] time [s] Calls Function 17.0500 17.0499 00.0001 1 P3 05.1971 05.1971 00.0000 1 P5 01.6834 01.6833 00.0001 1 P4 00.1542 00.1541 00.0001 1 P2 00.0566 00.0566 00.0000 1 P1 24.1414 00.0001 24.1413 1 MAIN 00.0003 00.0003 00.0000 3 HELPER Tabela 2. Czasy wykonania podprogramów przed optymalizacją procedury P3 Na podstawie danych w tabeli 2 widać, że największy całkowity czas na wykonanie podprogramu dotyczy procedury Main() (24.1414 s) oraz P3() (17.0500 s). W przypadku pierwszej z nich czas na własne zadania jest minimalny (00.0001 s), a praktycznie cały czas jej wykonania związany jest z oczekiwaniem aż wywołane podprogramy skończą swoje działanie (24.1413 s). Nie jest to zaskoczeniem, ponieważ programy są pisane właśnie w taki sposób działanie programu głównego sprowadza się do wywołania kilku podprogramów. Z kolei procedura P3() zdecydowaną większość czasu spędziła na wykonywaniu zadań własnych (11.0499 s), a czas spędzony na oczekiwaniu na wykonanie wywołanych podprogramów jest minimalny (0.0001 s). Na tej podstawie można wnioskować, ze właśnie procedura P3() jest miejscem, gdzie należy szukać możliwości optymalizacji. Optymalizacja czasu jej wykonania w największym stopniu przyczyni się do krótszego wykonania całego programu. Czasy wykonania poszczególnych podprogramów po optymalizacji procedury P3() przedstawione są w tabeli 3. Wyraźnie widać, ze czas na zadania własne tej procedury spadł do 5.4573 s, a co za tym idzie również czas całkowity (subtree time) procedury Main().

48 Piotr Węsław Subtree Self (function) Callees (descendants) time [s] time [s] time [s] Calls Function 05.4574 05.4573 00.0001 1 P3 05.0104 05.0104 00.0000 1 P5 01.6087 01.6086 00.0001 1 P4 00.1489 00.1488 00.0001 1 P2 00.0560 00.0560 00.0000 1 P1 12.3449 00.0550 12.2899 1 MAIN 00.0003 00.0003 00.0000 3 HELPER Tabela 3. Czasy wykonania podprogramów po optymalizacji procedury P3 Podany przykład ilustruje, że procedury, które mają duży czas przeznaczony na zadania własne (self time), a jednocześnie czas oczekiwania na inne podprogramy (callees time) jest niewielki, są dobrymi kandydatami do optymalizacji. 5.3. Przykład 3 koszt mechanizmu wywołania podprogramu Kolejny przykład ilustruje koszt mechanizmu wywołania podprogramów oraz jego wpływ na wydajność aplikacji w sytuacji, gdy jest on używany bardzo wiele razy. Struktura programu użytego w tym przykładzie przedstawiona jest na rys. 4. Program główny wywołuje kolejno funkcje od F1() do F5(). Ilość wywołań dla każdej kolejnej funkcji stopniowo rośne i jest zaznaczona na rysunku. Main 10 100 1000 10000 100000 F1 F2 F3 F4 F5 Rys. 4. Struktura wywołań programu użytego w przykładzie 3 Kod każdej z funkcji jest identyczny i sprowadza się jedynie do zwrócenia stałej wartości Przykładowo, kod funkcji F5() przedstawiony jest poniżej: function f5 return integer is begin return 5; end f5; Wyniki na podstawie przeprowadzonego eksperymentu oraz otrzymanych raportów zostały przedstawione w tabeli 4. Niepokojący jest fakt, ze główny program Main() ma stosunkowo duży czas na zadania własne (0.155661 s), mimo, że w zasadzie nie wykonuje on żadnych zadań, a jedynie woła funkcje od F1() do F5(). Jednocześnie funkcja F5() czas na zadania własne ma bardzo duży (0.090397 s) w porównaniu do tego co wykonuje w rzeczywistości ciało tej funkcji jest puste, co widać w kodzie przedstawionym powyżej. Z drugiej strony czas jej oczekiwania na wykonanie podprogramów wynosi 0 s. Nie jest to zaskoczeniem, ponieważ funkcja F5() nie wywołuje żadnych podprogramów.

PL/SQL Hierarchical Profiler jako zaawansowana metoda strojenia wydajności aplikacji 49 Analizując dalej czasy funkcji od F4() do F1() poświęcone na zadania własne (self time) widać, że maleją one mniej więcej proporcjonalnie do ilości wywołań (calls). Na podstawie powyższych faktów można przypuszczać, że większość czasu działania programu poświęcana jest na sam machizm wywoływania podprogramów. Subtree Self (function) Callees (descendants) time [s] time [s] time [s] Calls Function 00.255906 00.155661 00.100245 1 MAIN 00.090397 00.090397 00.000000 100000 F5 00.008760 00.008760 00.000000 10000 F4 00.000927 00.000927 00.000000 1000 F3 00.000147 00.000147 00.000000 100 F2 00.000015 00.000015 00.000000 10 F1 Tabela 4. Czas wykonania podprogramów przed użyciem mechanizmu inline Aby zredukować ilość wywołań podprogramów, jednocześnie zachowując funkcjonalność całego programu, można użyć mechanizmu inline. Mechanizm ten przed kompilacją programu modyfikuje w sposób automatyczny kod źródłowy w taki sposób, że miejsca wywołań danego podprogramu zastępowane są jego ciałem. Mechanizm inline może być użyty w następujący sposób: pragma Inline(f5, 'yes'); Po wprowadzeniu powyższej modyfikacji i wykonaniu eksperymentu, czasy wykonań poszczególnych podprogramów przedstawione zostały w tabeli 5. Czas całkowity programu Main() spadł z 0.255906 s do 0.042651 s, czyli około 6 razy jest to znaczna poprawa wydajności. Jednocześnie funkcja F5() całkowicie znikła z listy podprogramów. Wynika to z istoty działania mechanizmu inline. Po jego zastosowaniu funkcja F5() nie była już wywoływana, ponieważ jej zawartość została wstawiona w miejsce jej wywołań. Subtree Self (function) Callees (descendants) time [s] time [s] time [s] Calls Function 00.042651 00.033151 00.009500 1 MAIN 00.008227 00.008227 00.000000 10000 F4 00.001051 00.001051 00.000000 1000 F3 00.000147 00.000147 00.000000 100 F2 00.000015 00.000015 00.000000 10 F1 Tabela 5. Czas wykonania podprogramów po użyciu mechanizmu inline Przykład ten ilustruje sytuację, w której słaba wydajność aplikacji związana jest z dużą liczbą wywołań podprogramów. Rozwiązaniem może być użycie mechanizmu inline. 5.4. Przykład 4 wydajność podprogramu zależna od miejsca wywołania Wydajność podprogramu może być zależna od miejsca, w którym został on wywołany. Związane jest to z wartościami przekazanych argumentów. Przykładowo, uruchamiając program o strukturze przedstawionej na rys 3., może okazać się że 80% czasu działania podprogramu Helper() związane jest z jego wywołaniem przez podprogram P4(). Wywołania z podprogramów P2() oraz P3() stanowią zaledwie 20%. W takiej sytuacji konieczne będzie przeanalizowanie kodu źródło-

50 Piotr Węsław wego, aby zrozumieć czym różnią się te wywołania, np. podprogram P4() używa bardziej szczegółowego logowania wykonywanych zadań. PL/SQL Hierarchical Profiler a umożliwia potwierdzenia faktu, że takie zjawisko ma miejsce. Raporty otrzymane na podstawie przeprowadzonych eksperymentów zawierają szczegółowe sekcje dotyczące każdego podprogramu oraz miejsc, z którego był on wywoływany. Dla każdego nadrzędnego podprogramu podany jest jego procentowy udział w całkowitym czasie wykonania badanego podprogramu. Dzięki takiej informacji łatwo jest wskazać miejsce w kodzie aplikacji, z którego wywołania trwają nadspodziewanie długo. 6. Wpływ profilowania hierarchicznego na czas eksperymentu Profilowania hierarchiczne bazuje na rejestracji informacji o kolejnych wywołaniach procedur i funkcji. Informacje takie zapisywane są do pliku, co z kolej przekłada się na wydłużenie czasu eksperymentu. Jego wydłużenie zależy od ilości wywołań. Im więcej informacji jest zapamiętywanych, tym wpływ profilowania hierarchicznego jest większy. W tableach 6, 7 i 8 przedstawione są czasy z przebiegu trzech eksperymentów (różne programy testowe) w zależności od ilości wywołań podprogramów. Wyraźnie widać, ze wraz ze wzrostem liczby wywołań rzeczywisty czas eksperymentu znacznie rośne. Nie jest to powodem do zmartwienia, ponieważ czas ten w zasadzie nie ma wpływu na przeprowadzona później analizę. Natomiast czas podany przez PL/SQL Hierarchical Profiler a jest podstawą do analizy problemu wydajnościowego. Na podstawie zaprezentowanych wyników widać, ze czas ten również jest w pewien sposób zaburzony przez eksperyment. Na szczęście nie odbiega on znacząco od czasu wykonania programu bez użycia profilowania hierarchicznego. Ilość wywołań funkcji w całym eksperymencie 112 Czas zmierzony profilowanie wyłączone 36.23 s Czas zmierzony profilowanie włączone 36.61 s Czas podany przez profilera 36.58 s Tabela 6. Wpływ profilowania na czas eksperymentu 112 wywołań podprogramów Ilość wywołań funkcji w całym eksperymencie 11 112 Czas zmierzony profilowanie wyłączone 00.02 s Czas zmierzony profilowanie włączone 00.27 s Czas podany przez profilera 00.04 s Tabela 7. Wpływ profilowania na czas eksperymentu 11112 wywołań podprogramów Ilość wywołań funkcji w całym eksperymencie 111 112 Czas zmierzony profilowanie wyłączone 00.08 s Czas zmierzony profilowanie włączone 01.60 s Czas podany przez profilera 00.26 s Tabela 8. Wpływ profilowania na czas eksperymentu 111112 wywołań podprogramów Przeprowadzając strojenie wydajności w rzeczywistym systemie warto mieć na uwadze fakt, że informacje widoczne w raportach obarczone są pewnym błędem, którego nie można całkowicie wyeliminować.

PL/SQL Hierarchical Profiler jako zaawansowana metoda strojenia wydajności aplikacji 51 7. Rola profilowania hierarchicznego w strojeniu wydajności aplikacji Użycie profilowania hierarchicznego w strojeniu wydajności aplikacji może dostarczyć informacji, które pomogą podjąć decyzje gdzie i w jaki sposób podjąć próby jej poprawy. Poniżej zaprezentowana została lista wskazówek, która w połączeniu z analizą raportów z profilowania hierarchicznego ułatwi przeprowadzenie efektywnej optymalizacji. Kolejność zalecanych czynności nie jest przypadkowa i powinna być wykonywana w następującej kolejności: jeżeli czas wykonania programu zdominowany jest przez polecenia SQL zajmij się strojeniem wydajności zapytań. jeżeli występuje jeden podprogram PL/SQL owy ze znacznym czasem przeznaczonym na zadania własne (self time) zajmij się poprawą implementacji tego podprogramu. Jeśli analiza podprogramu poprzez jego czytanie nie jest wystarczająca profilowanie oparte o śledzenie poleceń.może być pomocne. jeżeli podprogramy wywoływany i wywołujący mają duże czas przeznaczone na zadania własne (self time) oraz ilość wywołań jest duża użyj mechanizmu inline, aby zmniejszyć koszt wywołań. jeżeli podprogram ma duży czas przeznaczony na zadania własne (self time), wywoływany jest z wielu miejsc, a czas jego wykonania zależy od miejsca wywołania sprawdź te miejsce wywołania, z którego czas wykonania jest największy. jeżeli powyższe przypadki nie mają zastosowania przeanalizuj tą część raportu (a następnie kodu PL/SQL), która ma największy całkowity czas wykonania. Rozwiązanie problemu może wymagać zmiany projektu aplikacji. 8. Podsumowanie PL/SQL Hierarchical Profiler jest kolejnym narzędziem dostarczonym przez Oracle przeznaczonym do optymalizacji wydajności aplikacji. Jego funkcjonalność umożliwia wskazanie problemów w kodzie PL/SQL, które do tej pory były trudne do znalezienia, a tym bardziej do udowodnienia. Opisany w niniejszym opracowaniu model koncepcyjny oraz zawarte przykłady ułatwią analizę dostarczanych przez te narzędzie raportów. W dalszej kolejności może przełożyć się to do bardziej efektywnej pracy zespołów zajmujących się strojeniem wydajności aplikacji. Bibliografia [Llew09] [Orcl08] Llewellyn B.: Using the PL/SQL Hierarchical Performance Profiler, Materiały Konferencyjne Oracle Open Word 2009, San Francisco, USA. Oracle Corporation: Using the PL/SQL Hierarchical Profiler, Oracle Database Advanced Application Developer's Guide 11g Release 1 (11.1), Part Number B28424-03, chapter 9.