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.
2
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:
Czas
Koszt
Analiza
Projektowanie
Implementacja
Rys. 1 Koszt optymalizacji podczas czasu „życia” aplikacji
Czas
Koszt
Analiza
Projektowanie
Implementacja
Rys. 2 Korzyści z optymalizacji podczas czasu „życia” aplikacji
3
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
4
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
5
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.
6
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.
7
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
8
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.
9
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
10
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
11
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.