Aspekty wydajności systemów opartych na bazie danych
Transkrypt
Aspekty wydajności systemów opartych na bazie danych
V Konferencja PLOUG Zakopane Październik 1999 Aspekty wydajności systemów opartych na bazie danych Oracle Paweł Radziulis Instytut Technik Telekomunikacyjnych i Informatycznych, Poznań Autor: Absolwent Akademii Techniczno-Rolniczej w Bydgoszczy. Od roku członek Zespołu Systemów Informatycznych i Multimediów, Instytutu Technik Telekomunikacyjnych i Informatycznych w Poznaniu. Streszczenie: Zadowolenie użytkowników, które jest miarą jakości systemu informatycznego zależy w dużej mierze od wydajności systemu (czas reakcji systemu, czas realizowania poleceń itd.). Zapewnienie odpowiedniej wydajności systemu jest kluczowym problemem w sytuacji gdy przewiduje się, że system ma obsługiwać wielu użytkowników w tym samym czasie. 1. Wstęp Podstawowym narzędziem uzyskania dobrej wydajności jest optymalizacja aplikacji i systemu bazy danych. Optymalizacja jest najbardziej efektywna kiedy przeprowadzana jest podczas kolejnych faz projektowania aplikacji, a nie czasie wdrażania gotowego systemu. Optymalizacja aplikacji powinna być przeprowadzana w etapach analizy i projektowania aplikacji. Przy silnej współpracy projektantów systemu oraz pionu kierowniczego klienta muszą zostać określone dokładnie cele stawiane aplikacji oraz realistyczne prognozy wydajności nowego systemu podczas jego pierwszego uruchomienia. Podczas etapu analizy i projektowania aplikacji projektanci mogą określić wtedy jaka kombinacja konfiguracji nowego systemu i możliwości udostępnianych przez Oracle’a dadzą najbardziej wydajny system. Poprzez optymalizacje podczas tych dwóch etapów minimalizowane są w bardzo dużym stopniu ewentualne koszty związane z późniejszym przebudowywaniem aplikacji bądź systemu. Rys.1 pokazuje względny koszt optymalizacji podczas czasu „życia” aplikacji, zaś rys. 2 korzyści z optymalizacji podczas czasu „życia” aplikacji: Koszt Analiza Projektowanie Implementacja Czas Rys. 1 Koszt optymalizacji podczas czasu „życia” aplikacji Koszt Analiza Projektowanie Implementacja Czas Rys. 2 Korzyści z optymalizacji podczas czasu „życia” aplikacji 2 Optymalizacja systemu bazy danych przeprowadzana w czasie wdrożenia systemu ograniczyć się może tylko do konfiguracji pamięci oraz optymalizacji procesów wejścia / wyjścia systemu. Podczas implementacji systemu może okazać się, że zarówno baza Oracle jak i sam system operacyjny działają w najbardziej wydajnej konfiguracji, a sama aplikacja nie spełnia naszych oczekiwań. Jedynymi metodami poprawienia współczynników wydajnościowych jest optymalizacja samej aplikacji lub zwiększenie zasobów systemu komputerowego. Cele jakie stawia się podczas optymalizacji zależą od typu aplikacji. Aplikacje typu OLTP (ang. Online Transaction Processing) obsługujące bardzo wiele prostych operacji jednocześnie za podstawę wydajności przyjmą efektywność działania zasobów oferowanych przez system. W przeciwieństwie do nich aplikacje DSS (ang. Decision Support System) ukierunkowane są na obsługę małej ilości użytkowników jednocześnie, a podstawą miary ich wydajności jest szybkość odpowiedzi systemu. Ponieważ czas odpowiedzi systemu równy jest czasowi obsługi procesu przez system oraz czasowi oczekiwania na odpowiedź, wydajność można zwiększyć tu na dwa sposoby: • przez redukcję czasu obsługi przez system; • przez redukcję czasu oczekiwania na odpowiedź. Np. w systemach wieloprocesorowych poszczególne zadania mogą być realizowane natychmiast wykorzystując zasoby (procesory) przydzielone tylko do ich dyspozycji. Efektywność działania zasobów oferowanych przez system mierzona jest jako ilość skończonej pracy w zadanej ilości czasu. Istnieją dwie techniki zwiększania wydajności zasobów systemu: • Zwiększenie ilości wykonanej pracy w oparciu o te same zasoby – redukcja czasu obsługi. • Zwiększenie szybkości pracy systemu poprzez skrócenie czasu oczekiwania na odpowiedź. Czas oczekiwania na odpowiedź związany jest ściśle z takimi zasobami systemu jak procesory, pamięć, operacje wejścia / wyjścia. Zwiększenie tych zasobów, a szczególnie tych, które powodują długie czasy oczekiwania na odpowiedź, zwiększa wydajność systemu oraz zmniejsza czasy oczekiwania na odpowiedź. 2. Kolejność kroków optymalizacji Najlepsza metoda optymalizacji opiera się na liście kroków uporządkowanych według zysku jaki uzyskuje się poprzez ich wykonanie oraz etapy projektu, w których powinny być wykonane tzn. od analizy poprzez projektowanie do implementacji. Czym krok jest wcześniejszy tym więcej korzyści można osiągnąć podczas jego wykonywania. Krok 1: Zmiana reguł biznesowych Krok 2: Projektowanie modelu danych Krok 3: Projektowanie aplikacji Krok 4: Projektowanie logicznej struktury bazy danych Krok 5: Optymalizacja operacji na bazie danych Krok 6: Optymalizacja ścieżek dostępu Krok 7: Optymalizacja konfiguracji pamięci operacyjnej Krok 8: Optymalizacji operacji wejścia / wyjścia 3 Krok 9: Optymalizacja blokad zasobów Krok 10: Optymalizacja systemu operacyjnego 3. Zmiana reguł biznesowych Jednym z kroków zwiększenia wydajności jest dostosowanie reguł biznesowych. Jest to proces bardzo dokładnych analiz oraz projektowania całego systemu. Na etapie tym projektanci muszą określić czy wymagania wydajności systemu odpowiadają ściśle potrzebom biznesowym klienta. Często podczas analizy systemu funkcje biznesowe aplikacji są tworzone zbyt szczegółowo. Szczegółowość taka nie mająca widocznego wpływu na efekt działania funkcji może w poważnym stopniu ograniczyć możliwości programistów w kierunku uzyskania jak najlepszych parametrów wydajnościowych dla danych funkcji, poprzez ograniczenie ich pola działania. A czym więcej możliwości mają do wyboru programiści tym większa szansa na osiągniecie wysokich współczynników wydajności systemu lub aplikacji. 4. Projektowanie modelu danych Podczas etapu definiowania danych należy określić jakie dane są konieczne do prawidłowego działania aplikacji, jakie posiadają atrybuty oraz jakie zależności pomiędzy nimi istnieją oraz które z nich są najważniejsze. Generalnie proces projektowania bazy danych opiera się na normalizacji. Jest to proces mający na celu wyeliminowanie z bazy danych redundancji. Czasami jednak konieczna staje się denormalizacja bazy danych w celu poprawienia wydajności jej działania. Np. kiedy projektanci stwierdzą, że najczęściej pobierane dane sumaryczne powinny być przechowywane w bazie danych a nie obliczane każdorazowo przez aplikację. W przypadku projektowania hurtowni danych bądź bazy danych operujących na bardzo dużych ilościach danych przydatne staje się partycjonowanie tabel. Partycjonowanie pozwala użytkownikowi na dekompozycję tabel i indeksów na mniejsze, łatwiejsze w zarządzaniu, fragmenty zwane partycjami. Każda z takich partycji traktowana jest jako osobny segment. Wszystkie partycje tabeli lub indeksu składają się z tych samych kolumn i posiadają te same definicje więzów integralności, lecz każda z nich może posiadać swoje własne parametry alokacji przestrzeni i być umieszczona w innej przestrzeni tabel. Dzięki partycjonowaniu tabel uzyskujemy: • Efektywniejsze ścieżki dostępu dla optymalizacji kosztowej. • Możliwości przeszukiwania tabel przy pomocy predykatów zakresu opartych o kolumnę partycjonowania. • Możliwość okresowego załadowywania lub usuwania danych poprzez dodawania lub usuwanie partycji. • Możliwości częściowej archiwizacji tabeli. Inną metodą redukcji obciążenia przeciążonego dysku jest przesunięcia najbardziej aktywnych plików na inne, mniej obciążone dyski. Jeśli wielu użytkowników jednocześnie wykonuje operacje na pewnej dużej 4 tabeli, to w celu zmniejszenia rywalizacji, należy ją rozłożyć pomiędzy różne pliki danych umieszczone na różnych dyskach. Ogólnie należy też dążyć do wyeliminowania operacji wejścia / wyjścia generowanych przez systemy nie związane z Oracle na dyskach, na których umieszczone są pliki bazy danych. Rozkładanie plików dokonać można poprzez system operacyjny (rozkładanie software’owe lub RAID) lub ręcznie (polecenia CREATE TABLE lub ALTER TABLE ALLOCATE). Dla szybkiego i łatwego wyszukiwania danych tworzy się indeksy kluczy własnych oraz kluczy obcych na istniejących relacjach pomiędzy tablicami. 5. Projektowanie aplikacji Podczas tworzenia aplikacji konieczne jest efektywne odwzorowanie procesów wykonywanych w firmie w sprawnie działający system. Każdemu takiemu procesowi odpowiada osobna aplikacja systemu bądź część aplikacji. Niejednokrotnie różne procesy korzystają w pewnych swych okresach z identycznych podprocesów – funkcji. Logiczne jest aby takie wyodrębnione bloki, wykorzystywane wielokrotnie lub wykorzystywane przez kilka procesów, były definiowane tylko jeden raz. Taką funkcję pełnią właśnie funkcje składowane oraz procedury składowane. 6. Projektowanie logicznej struktury bazy danych Podczas projektowania struktury bazy danych jedną z najważniejszych czynności jest przerobienie struktury indeksów. Poprawne skonfigurowanie indeksów ma większy wpływ na działanie aplikacji niż restrukturyzacja wyrażeń SQL lub przebudowa danych. Indeks zwiększa wydajność zapytań, które wybierają niedużą procentowo liczbę wierszy z tablicy. Zwykle indeksy zakłada się na tablicach, które są często przeszukiwane dla mniej niż 3 % do 4% wierszy w niej zawartych. Wartość ta może być większa w przypadku kiedy wszystkie żądane dane mogą zostać pobrane z indeksu bądź kiedy indeksowana kolumna będzie używana do tworzenia relacji z innymi tablicami. Tworzenie indeksów oparte jest na następujących założeniach i cechach charakterystycznych relacyjnych baz danych: • Wiersze posiadające tą samą wartość w kolumnie, na której oparte jest zapytanie, są niejednolicie rozmieszczone w bloku danych przestrzeni tablic przydzielonym dla tablicy z danymi. • Wiersze w tablicy są rozmieszczone losowo a ich układ nie odnosi się do żadnych kryteriów, na których opierają się zapytania. • Tablice zawierają stosunkowo małą liczbę kolumn. • Większość zapytań na tablicy ma względnie proste klauzule WHERE. • Częstotliwość odwołań do pamięci podręcznej jest względnie niska. 5 Jeśli powyższe założenia nie opisują danych zawartych w tablicach, do których odwołują się zapytania, wtedy indeksy nie będą miały dużego wpływu na przyspieszenie działania wyrażeń SQL dopóki zapytania nie będą dotyczyły przynajmniej 25% wierszy z tablicy. Mimo, że optymalizacja kosztowa jest idealna do zapobiegania użycia nieselektywnych indeksów podczas wykonywania zapytań, motor SQL musi cały czas podtrzymywać wszystkie indeksy zdefiniowane na danych tablicach, niezależnie od tego czy są one wykorzystywane czy nie. Podtrzymywanie indeksów ma znaczący wpływ na zasoby procesora i układu wejścia / wyjścia systemu dla każdej aplikacji obsługującej dużą ilość operacji wejścia / wyjścia. Innymi słowy tworzenie indeksów „na wszelki wypadek” nie jest dobrą praktyką. Indeks nie powinien być tworzony dopóki nie będzie miał być wykorzystany, a z sytemu powinny zostać usunięte wszystkie indeksy, które nie są używane. Detekcję indeksów, do których nie odnoszą się żadne zapytania dokonuje się poprzez analizę wszystkich zapytań SQL wykorzystywanych w aplikacji funkcją EXPLAIN PLAN i odczycie jej wyników. Przy wyborze kolumn do indeksów programista powinien kierować się poniższymi wskazówkami: • Należy brać pod uwagę kolumny, które są często wykorzystywane w klauzulach WHERE wyrażeń SQL. • Należy brać pod uwagę kolumny, które są wykorzystywane do tworzenia relacji pomiędzy tablicami. • Indeksy należy tworzyć na kolumnach mających procentowo małą liczbę wierszy o takich samych wartościach w kolumnie, do której ma odnosić się indeks. Należy pamiętać, że Oracle tworzy automatycznie indeksy na wszystkich kolumnach, na których zostały nałożone klucze unikatowe lub klucze własne. Indeksy te są najbardziej efektywne w procesie optymalizacji. 7. Optymalizacja operacji na bazie danych Optymalizację operacji na bazie danych można dokonać na dwa sposoby: • Wykorzystując procesy optymalizacji Oracle • Przez przebudowę poleceń SQL. Procesy optymalizacji Oracle udostępniają pracują w dwóch trybach: optymalizacji kosztowej i optymalizacji regułowej. Optymalizacja regułowa przynosi największe korzyści wykorzystywana w aplikacjach już istniejących. Zaś w celu uzyskania jak największych korzyści z nowych funkcjonalności tych procesów powinno stosować się regułę kosztową. Optymalizacja kosztowa generalnie wybiera plany wykonania zapytań lepsze od optymalizacji regułowej, szczególnie dla długich zapytań z wieloma powiązaniami bądź korzystających z wielu indeksów. W pewnym stopniu optymalizacja kosztowa eliminuje potrzebę optymalizacji samych zapytań SQL. Aby optymalizacja kosztowa zadziałała poprawnie konieczne jest wykonanie analiz na tablicach poleceniem ANALYZE. 6 8. Optymalizacja ścieżek dostępu W kroku tym należy przeanalizować efektywność dostępu do danych. Jeśli okaże się, że jednoczesny dostęp wielu użytkowników blokowany jest przez ograniczony dostęp do tablic, należy zastanowić się nad użyciem klastrów, hash-klastrów oraz indeksów. Klastry tworzy się na tablicach, do których zapytania odwołują się jednocześnie. W klastrze przechowywane są wiersze posiadające ten sam klucz klastra. Każda różna wartość klucza przechowywana jest tylko raz niezależnie od ilości tablic lub wierszy, w których występuje. Oszczędza to miejsce na dysku i przyspiesza wiele operacji dostępu do danych ściśle powiązanych ze sobą. Dla każdego klastra przed jego użyciem konieczne jest stworzenie własnego indeksu. Odmianą klastra są hash-klastry. Różnica polega tylko na tym, że kluczami są tu wartości hash funkcji. Funkcje takie tworzone są przez użytkowników bądź wykorzystywana jest, któraś z funkcji istniejących już w systemie Oracle. Do przyspieszenia dostępu, szczególnie do grup danych , mogą służyć indeksy grupowe i bitmapowe. Indeks grupowy jest to indeks, który odnosi się do więcej niż jednej kolumny w tablicy. Indeksy grupowe posiadają lepszą selektywność, niż indeksy zakładane na pojedynczych kolumnach. Czasami dwie lub więcej kolumn, każda o słabej selektywności, mogą być połączone w indeksie zapewniając dobrą efektywność wyszukiwania po danej tablicy. Dodatkowo indeksy te pozwalają na przechowywanie dodatkowych danych. Jeżeli wszystkie dane, które pobierane są w zapytaniu z danej tablicy, zawarte są w indeksie grupowym założonym na tej tablicy, Oracle pobierze te dane bez konieczności wyszukiwania ich w tablicy. Wyrażenie SQL wykorzysta indeks grupowy jeżeli jego struktura będzie zawierała początkowa cześć indeksu. Początkowa część indeksu to zestaw jednej lub więcej kolumn, które znajdują się na początku i to uporządkowane w kolejności jakiej znajdują się na liście kolumn w wyrażeniu CREATE INDEX, które stworzyło indeks. Tworzenie indeksów grupowych należy brać pod uwagę w następujących przypadkach: • kiedy w klauzuli WHERE znajdują się kolumny z jednej tablicy i są od siebie oddzielone operatorem AND; • jeżeli kilka zapytań korzysta z tego samego zestawu wartości pobieranych z jednej lub więcej kolumn z jednej tablicy. System Oracle udostępnia także indeksy bitmapowe, których zalety wykorzystuje się tam gdzie zawodzą indeksy B*-tree. Indeksy bitmapowe mogą znacznie zwiększyć wydajność zapytań o następujących charakterystykach: • klauzule WHERE zawierają zbiorowe zapytania na mało lub średnio ważnych kolumnach; • pojedyncze zapytanie na mało lub średnio ważnych kolumnach zwraca dużą ilość wierszy; • tablica, na której wykonywane jest zapytanie posiada bardzo dużą liczbę wierszy. Zalety indeksów bitmapowych najlepiej są wykorzystywane przy złożonych zapytaniach zawierających długie klauzule WHERE, oraz zapytaniach łączonych ze sobą. W porównaniu z indeksami łączonymi B*-tree indeksy bitmapowe mogą znacznie zaoszczędzić zasoby systemu podczas gromadzenia danych. W bazie zawierającej tylko indeksy B*-tree, administrator musi 7 określić kolumny, które będą lub mogą być wykorzystywane razem w klauzulach WHERE i na tej podstawie stworzyć indeks grupowy. Indeks taki wymaga dużej ilości pamięci ze względu na przechowywanie danych z kilku kolumn. Oprócz tego indeks taki musi zostać uporządkowany. Oznacza to, że baza musi stworzyć indeksy na możliwość wystąpienia wszystkich permutacji kolumn, na których został stworzony indeks grupowy. Dla indeksu grupowego na trzech kolumnach zostanie stworzonych sześć niezależnych indeksów typu B*-tree. Indeksy bitmapowe rozwiązują ten problem. Są one efektywnie wiązane ze sobą dopiero podczas wykonywania zapytania. Indeksy bitmapowe utworzone osobno na trzech kolumnach wykonają taką samą pracę jak sześć indeksów grupowych typu B*-tree utworzonych na tych trzech kolumnach. Dla kolumn gdzie dana wartość powtórzona jest kilkaset lub kilka tysięcy razy, indeks bitmapowy zajmie około 25% pamięci potrzebnej indeksowi typu B*-tree. Efekt ten jest otrzymywany dzięki temu, że indeksy bitmapowe przechowywane są w formie skompresowanej. Cecha ta nie dotyczy kolumn, na których założone są klucze unikatowe. Wydajniejsze stają się wtedy zwykłe indeksy B*-tree. 9. Optymalizacja konfiguracji pamięci operacyjnej Konfiguracja pamięci operacyjnej ma trzy główne cele: • redukcja operacji stronicowania i przerzucanie danych „swapping”; • umieszczenie SGA w głównej pamięci; • rezerwacja wystarczającej ilości pamięci dla poszczególnych użytkowników. System operacyjny może gromadzić informacje w pamięci operacyjnej, pamięci wirtualnej, zewnętrznych nośnikach danych lub na dyskach. Odpowiednie mechanizmy pozwalają na przenoszenie informacji (danych) pomiędzy tymi różnymi mediami. Procesy te to stronicowanie i „swapping”. Procesy te uaktywniają się w momencie wprowadzania dużej ilości nowych danych do systemu i prowadzą do zwolnienia wykonywanych poleceń. W takim przypadku należy zwiększyć ilość pamięci operacyjnej bądź zmniejszyć ilość pamięci rezerwowanej dla użytkowników. Ponieważ dostęp do pamięci operacyjnej jest o wiele szybszy od dostępu do dysków, wskazane jest aby cały SGA był ładowany do głównej pamięci. W przypadku kiedy część danych SGA zostanie przerzucona na dysk spowoduje to redukcję szybkości dostępu do tych danych. Kiedy dane te są niewykorzystywane nie tylko nie zmniejsza to wydajności systemu, ale zwiększa ilość dostępnej pamięci operacyjnej. Oracle udostępnia opcję automatycznego ładowania całego SGA do pamięci komputera w momencie uruchamiania instancji. W tym celu należy ustawić parametr inicjalizujący PRE_PAGE_SGA na YES. Ustawienie to może zwiększyć czas potrzebny na uruchomienie instancji, ale za to zmniejszy czas potrzebny na osiągnięcie pełnej funkcjonalności przez bazę Oracle. Obszar SGA można generalnie podzielić na trzy części: • bufor danych - przechowuje kopie danych odczytanych z plików; • bufor dziennika powtórzeń - przechowuje zapisy o wszystkich operacjach DML i DDL; • globalny obszar dzielony. Optymalizację można przeprowadzić na wszystkich tych częściach. 8 Ponieważ operacje wejścia / wyjścia zabierają znaczną ilość czasu i zwiększają obciążenie procesora, to wydajność pracy Oracle może być znaczeni zwiększona, jeśli procesy serwera większość potrzebnych bloków znajdować będą w pamięci. Statystyką, która pozwala na zmierzenie wydajności bufora danych jest współczynnik trafień w bufor. Statystyka ta to iloraz liczby bloków znalezionych w pamięci do liczby wszystkich bloków, na których procesy serwera wykonywały operacje. Jeśli bufor danych jest zbyt mały, to wydajność systemu jest niska, gdyż musi on wykonywać wiele operacji wejścia / wyjścia. Celem strojenia bufora danych jest zachowanie w pamięci wszystkich danych wykorzystywanych przez serwer oraz utrzymanie współczynnika trafień dla systemów OLTP powyżej 90%. Aby zwiększyć współczynnik trafień w bufor danych można: • zwiększyć rozmiar bufora danych (przechowywanie większej ilości danych) • stosowanie wielu pul buforów w celu oddzielenia bloków o różnych charakterystykach dostępu • buforować w pamięci całe tabele. Każda operacja wykonana na bazie Oracle jest przechowywana w buforze dziennika powtórzeń, a potem w plikach dziennika powtórzeń na dysku, zatem prawidłowe skonfigurowanie tego bufora może mieć znaczący wpływ na poprawę wydajności systemu. Nastrojenie tego bufora powinno zapewnić wystarczającą przestrzeń dla wszystkich potrzebujących procesów serwera oraz zminimalizowanie niepotrzebnie rezerwowanej pamięci operacyjnej. Wartość parametru określającego wielkość bufora dziennika powtórzeń zależna jest w dużej mierze od systemu operacyjnego. Zwykło się przyjmować, że powinna być czterokrotnie większa od maksymalnego rozmiaru bloku danych. Globalny obszar dzielony składa się z: • bufora bibliotecznego - przechowującego dzielone przez użytkowników polecenia SQL i bloki PL./SQL, • bufora słownika danych – przechowującego definicje obiektów słownikowych, • globalnego obszaru użytkownika. Celem strojenia globalnego obszaru dzielonego jest: • redukcja analiz do minimum (jeśli w buforze znajduje się już analiza polecenia SQL, które jest wywoływane przez serwer, to jego gotowy wynik zostanie pobrany bezpośrednio z pamięci, a nie jeszcze raz przeliczany) – współczynnik trafień w obszar dzielony powinien być większy niż 90%; • zmniejszenie stosunku ponownych załadowań do żądań w buforze bibliotecznym do poziomu poniżej 1%; • zmniejszenie stosunku braków do żądań w buforze słownika danych do poziomu poniżej 15%. Niedogodnością optymalizacji globalnego obszaru dzielonego jest konieczność każdorazowego testowania wprowadzanych zmian na działającej bazie i aplikacjach. 10. Optymalizacja operacji wejścia / wyjścia Większość dysków posiada limit na ilość jednoczesnych dostępów do niego jak i ilości danych jakie można z niego odczytać jednocześnie. W momencie kiedy z operacji odczytu z dysku będzie chciało skorzystać zbyt wielu użytkowników i przekroczony zostanie któryś z powyższych parametrów, nastąpi 9 spowolnienie wykonywania niektórych procesów. Co odzwierciedli się w spadku wydajności systemu. Aby nie dopuścić do takich sytuacji zalecane są następujące czynności: Oddzielenie plików danych od plików dziennika powtórzeń – pliki dziennika powtórzeń zapisywane są sekwencyjnie przez proces LGWR, a umieszczenie ich na dyskach nie obciążonych spowoduje iż operacja zapisu do tych plików nastąpi o wiele szybciej i nie spowolni jednoczesnego dostępu do plików danych. Partycjonowanie tablic - partycjonowanie dzieli tabele i indeksy na mniejsze, łatwiejsze w zarządzaniu, fragmenty zwane partycjami, a każda z takich partycji traktowana jest jako osobny segment. Eliminacja operacji wejścia / wyjścia procesów nie związanych z Oracle na dyskach z plikami danych bądź plikami dziennika powtórzeń. 11. Optymalizacja blokad zasobów W systemach wykorzystywanych jednocześnie przez wielu użytkowników spowolnienie pracy może następować z powodu blokady dostępu do bloków danych na dysku lub w pamięci w wyniku zbyt dużej liczby jednoczesnych odwołań. Spadek wydajności systemu następuje w wyniku kolejkowania kolejnych procesów w systemie. Jedną z możliwości niwelowania tego stanu jest zmiana wielkości bloków danych. Każda tablica danych w systemie jest składowana w postaci bloków danych. Najlepszą wydajność otrzymuję się kiedy w pojedynczym cyklu odczytu otrzymujemy wszystkie żądane dane z bloku. Czym bloki danych są mniejsze tym krótsze są cykle odczytu i łatwiejszy dostęp wielu użytkowników. Jednakże wielkość bloków danych jest płynna w zależności od aplikacji, które obsługują bazę danych. Np. dla aplikacji typu OLTP, gdzie duża ilość użytkowników generuje jednocześnie wiele zapytań, optymalna wielkość bloków danych to 2K – 4K. Wraz ze wzrostem złożoności tabel (ilości kolumn) wielkość ta powinna systematycznie rosnąć, aż do 64K dla aplikacji typu DSS, gdzie dostęp do dużej ilości danych następuje sekwencyjnie. 12. Optymalizacja systemu operacyjnego Kiedy został zakończony proces optymalizacji systemu bazy danych, można spróbować skonfigurować system operacyjny. Trzeba jednak wiedzieć, że konfiguracja ta nie przyniesie wielkiego wzrostu wydajności. Jednymi z możliwych parametrów konfiguracyjnych systemu operacyjnego mających bezpośredni wpływ na bazę danych jest ilość i położenie plików wymiany oraz priorytet procesów pierwszo- i drugoplanowych Oracle (na systemach UNIX). 13. Podsumowanie Spośród wymienionych powyżej metod najłatwiejsze w realizacji oraz dające znaczną poprawę wydajności systemu bazy danych to zastosowanie optymalizacji kosztowej Oracle wraz z wykonaniem analiz tablic systemu oraz strojenie pamięci operacyjnej systemu. W pierwszym przypadku przy bardzo niewielkim wkładzie pracy uzyskać można nawet dwukrotne przyspieszenie wykonywania dowolnych operacji na bazie 10 danych. W szczególnych przypadkach funkcji składowanych, typowo matematycznych, przyspieszenie może osiągnąć wartość ponad 100 razy. W przypadku strojenia samej pamięci operacyjnej systemu wkład pracy jest już znacznie większy. Stajemy przed koniecznością testowania wielu zestawu parametrów, często zmiana tych parametrów powiązana jest z restartem bazy danych. W przeprowadzonych testach na platformie Windows NT poprzez zmianę samego parametru DB_BLOCK_BUFFERS uzyskano zwiększenie wydajności systemu o prawie 25%. Dość znaczne przyspieszenie działania systemu można osiągnąć poprzez odpowiednie zaprojektowanie samej aplikacji. Jest to łatwe do uzyskania szczególnie w przypadku aplikacji, której formularze korzystają z wielu zakładek. Najczęściej zakładki stosowane są w formularzach, które zawierają i wyświetlają duże ilości danych. Poprzez sekwencyjne ładowanie i doczytywanie danych, dla każdej widocznej zakładki osobno, odciążamy serwer od wielu czasami niepotrzebnie wykonywanymi operacjami (w przypadku gdy użytkownik korzysta tylko z jednej zakładki, a dane są pobierane lub obliczane dla całego formularza) oraz dokonujemy „widocznego” przyspieszenia działania systemu. Krytycznymi punktami procesu optymalizacji systemu są kroki tworzenia reguł biznesowych oraz projektowania samego modelu danych. Etapy te opierają się na ścisłej współpracy projektanta z klientem. Ścierają się wtedy dwie koncepcje struktury systemu. Jedna - klienta jak najbardziej zbliżona do potrzeb procesów firmy odwzorowywanych w systemie, ale z reguły mało optymalną pod względem wydajności. Druga - projektanta zachowująca pełne funkcjonalności poprzedniej, ale uwzględniająca aspekt wydajności działania systemu. Najważniejszym elementem tych etapów do jakich musi dążyć projektant jest ograniczenie w modelu danych liczby powiązań typu „wiele do wiele”. Jest to typ powiązań, który bardzo często pojawia się w modelu danych preferowanym przez klienta. W większości przypadków możliwe jest przemodelowanie systemu tak, aby powiązania te zastąpić powiązaniami typu „jeden do wielu”, co uchroni projektantów aplikacji od konieczności tworzenia bardzo skomplikowanych skryptów SQL znacznie spowalniających pracę systemu. Są to etapy najtrudniejsze dla projektantów, ponieważ często muszą oni uświadomić klienta, że proces optymalizacji systemu nie zaczyna się w chwili jego wdrażania, ale trwa przez cały okres projektu. A zmiany które przedstawiane są przez niego są konieczne do efektywnego działania systemu. Jak można zauważyć z powyższych rozważań proces optymalizacji systemu jest problemem bardzo złożonym. Dotyczy zarówno aplikacji, bazy danych oraz systemu operacyjnego. Rozciągnięcie jego na cały okres tworzenia systemu jest jednym z kluczowych zadań jakie stoją przed projektantami i programistami. Zbagatelizowanie albo opuszczenie, któregoś z jego kroków może doprowadzić do konieczności zwiększenia nakładu pracy w pozostałych etapach tworzenia systemu bądź późniejszym braku możliwości optymalizacji systemu bez konieczności ponownego etapu projektowania całej aplikacji. A optymalizacja to podstawowy klucz do zwiększenia wydajności systemu. 11