Indeksy i ich zastosowanie
Transkrypt
Indeksy i ich zastosowanie
Bazy danych Indeksy 139 140 Bazy danych Przegląd zagadnień Dostep fizyczny do danych Optymalizacja dostepu Indeksy i ich zastosowanie Rodzaje indeksów Operacje na indeksach Podsumowanie Laboratorium Wykład stanowi wprowadzenie w świat indeksów. Indeksy są specjalnym mechanizmem bazy danych, który pozwala na przyspieszenie wyszukiwania danych. Jest to niewątpliwie bardzo waŜny parametr charakteryzujący bazę danych. Szczególnie w bazach zawierających wiele tysięcy rekordów mechanizm indeksów jest niezbędny do zapewnienia rozsądnych czasów wyszukiwania danych Bazy danych 141 Dostęp fizyczny do danych Zrozumienie mechanizmu dostępu do danych zapisanych w bazie danych jest bardzo istotny dla zrozumienia zasad działania indeksów. Jak wiadomo, dane w bazach danych w sposób trwały są zapisywane na dyskach optycznych, magnetycznych lub rodzinach nośników o dostępie bezpośrednim takich jak macierze RAID. Zasady działania tego typu nośników oraz pojęcia głowicy, cylindrów, strony danych itp. powinny być Ci znane z przedmiotu Podstawy Informatyki lub podobnego. SZBD najczęściej nie zajmuje się fizyczną obsługą dysków. W procesie dostępu do danych biorą udział: menedŜer plików i menedŜer dysku. MenedŜer plików ma odpowiednią wiedzę o strukturze systemu plików i jest odpowiedzialny za odszukanie odpowiedniego pliku. MenedŜer dysku ma natomiast niezbędną wiedzę na temat fizycznej organizacji dysku i jest odpowiedzialny za odnalezienie odpowiedniej strony danych. Schemat łańcucha dostępu do danych pokazany jest na rysunku 6.1. Rys.6.1 Schemat łańcucha dostępu do danych 142 Bazy danych Optymalizacja dostępu Zasadniczy czas dostępu do danych bazy to czas odczytu tych danych z dysków. W celu optymalizacji tego dostępu stosuje się metodę zwaną klastrowaniem. Klastrowanie polega na dąŜeniu do utrzymania blisko siebie na dysku rekordów, które są logicznie powiązane. Taka organizacja danych znacznie przyspiesza dostęp do danych. Aby odczytać dane powiązane (i w związku z tym zapewne razem wykorzystywane i odczytywane), głowica nie musi wykonywać duŜych ruchów, a tym samym maleją czasy wyszukiwania). RozróŜniamy przy tym dwa rodzaje klastrowania: • • - klastrowanie wewnątrzplikowe, - klastrowanie międzyplikowe. Klastrowanie wewnątrzplikowe polega na grupowaniu rekordów obok siebie wewnątrz jednego pliku. Klastrowanie międzyplikowe polega na umieszczaniu na stronie obok siebie rekordów pochodzących z więcej niŜ jednego pliku (tabeli). Optymalizacja dostępu do danych sprowadza się w zasadzie do odpowiedniego zarządzania stronami i decydowania w jaki sposób dane mają być klastrowane. Rys. 6.2Przechowywanie danych na dysku Jak to pokazano na rysunku 6.2, wszystkie dane z tabel relacyjnej bazy danych są przechowywane na stronach danych (ang. page) na dysku. Na przykład w serwerze MS SQL strona danych ma wielkość 8 KB. Strony tworzą większe struktury zwane stertami (ang. heap). Sterta jest kolekcją stron danych. W kaŜdej tabeli dane są przechowywane w kolekcji 8 kilobajowych stron. 8 ciągłych stron tworzy zakres (ang. extent). Wiersze danych nie są na stronach przechowywane w szczególnej kolejności, a strony danych nie są połączone w listę. Jeśli podczas wstawiania danych do strony, strona ulega przepełnieniu, to wtedy następuje podział takiej strony. PoniewaŜ jeden wiersz tabeli musi zmieścić się na stronie danych, więc w serwerze MS SQL występuje ograniczenie co do wielkości wiersza i wynosi ono 8060 bajtów (poniewaŜ na stronie zapisywane są jeszcze metadane informacje o obiekcie, którego dane przechowuje strona itd., dane nie zajmują dokładnie pełnych 8 KB). Bazy danych Rys. 6.3 Organizacja danych w serwerze MS SQL 143 144 Bazy danych Indeksy i ich zastosowanie Zastanowimy się teraz nad problemem wyszukiwania danych w tabeli. Na przykład załóŜmy, Ŝe w tabeli Studenci chcemy znaleźć studenta o nazwisku Nowak. Tabela 6.4 Przykładowa tabela bazy studentów ID Nazwisko Imie Wydzial 1 Olacki Jan Elektryczny 2 Babicki Adam Mechaniczny 3 Nowak Jerzy Elektryczny 1 Adamski Adam Elektronika Wiersze zapisane są w bazie w kolejności ich wpisywania i nie są w szczególny sposób sortowane. Co robi wobec tego system, kiedy wydajemy polecenie odnalezienia rekordu zawierającego informacje o Nowaku, np. SELECT imie, nazwisko FROM Studenci WHERE Nazwisko = 'Nowak'? System musi przeszukać całą tabelę (skanowanie wszystkich stron danych zawierających dane z tabeli) i przejrzeć wszystkie rekordy tej tabeli, aby mieć pewność, Ŝe odnalazł rekordy zawierające nazwiska Nowak. Operacja taka jest oczywiście czasochłonna. Podobnie jest, gdy w ksiąŜce poszukujemy jakiegoś hasła (na przykład w podręczniku do baz danych szukamy informacji o indeksach). Aby znaleźć szukaną informację, powinniśmy przeczytać całą ksiąŜkę. Na szczęście niektóre ksiąŜki są wyposaŜone na końcu w specjalne zestawienie haseł - czyli w indeks haseł. Nasze postępowanie przebiega wówczas następująco: 1. Odszukujemy poszukiwane hasło w indeksie, które jest uporządkowany alfabetycznie (co znacznie ułatwia nam odnalezienie hasła). 2. Odczytujemy w indeksie numer strony na której hasło to występuje w ksiąŜce. 3. Otwieramy ksiąŜkę na odpowiedniej stronie. 4. Przeglądamy stronę w poszukiwaniu naszego hasła. 5. Odczytujemy informacje związane z szukanym hasłem. Idea działania indeksów w bazie danych jest dokładnie taka sama. Indeks określony na atrybucie A relacji jest mechanizmem, który pozwala na efektywne wyszukiwanie krotek o ustalonej wartości składowej atrybutu A. Jak więc wyglądałby indeks dla tabeli Studenci? Indeks określany jest dla konkretnego pola. Mówimy wówczas, Ŝe pole to jest polem indeksowanym. W wypadku tabeli Studenci moŜemy jako pole indeksowane wybrać pole nazwisko. Wówczas załoŜenie indeksu na tym polu będzie oznaczało załoŜenie przez system dodatkowej tabeli, w której Bazy danych 145 umieszczone zostaną nazwiska studentów z tabeli Studenci oraz dostarczy przesłankę, gdzie naleŜy szukać (na której stronie danych) pełnej informacji o danym studencie. Dodatkowo rekordy w tabeli indeksu zostaną posortowane w kolejności alfabetycznej nazwisk. Poszukiwanie naszego studenta Nowaka będzie teraz przebiegać znacznie szybciej. Działanie i rola indeksów polega głównie na przyspieszeniu wyszukiwania rekordów w bazie danych. Niestety obciąŜają one dodatkowo system w czasie aktualizacji lub wstawiania danych. SZBD musi bowiem oprócz umieszczenia rekordu w bazie dokonać teŜ wpisu w tabeli indeksu oraz ponownie posortować rekordy tabeli indeksu. Zalety i wady stosowania indeksów zebrano w tabeli 6.5. Tabela 6.5 Zalety i wady stosowania indeksów Zalety Wady Przyspieszają dostęp do danych Zajmują miejsce na dysku Wymuszają unikatowość wierszy Zwiększają obciąŜenie sysetmu Niektóre z pól warto jest indeksować, inne natomiast nie powinny być nigdy indeksowane. Warto indeksować następujące pola: • • • klucze podstawowe i obce (często są automatycznie indeksowane), pola, po których często następuje wyszukiwanie, pola, do których dostęp następuje w ustalonej, uporządkowanej kolejności. Nie naleŜy indeksować: • • • pól, do których rzadko odwołują się zapytania, pól, które zawierają tylko kilka wartości unikatowych, pól zawierających dane typu image, bit czy obiekt OLE. Indeksy mogą być zakładane na jednym polu lub na większej liczbie pól jednocześnie. Dostęp do danych z wykorzystaniem indeksów nie zawsze jest najlepszym rozwiązaniem. Czasem lepiej jest nie korzystać z indeksów, ale bezpośrednio skanować tabelę. SZBD sprawdza, czy dla danej tabeli istnieją indeksy, a następnie optymalizator zapytań analizuje zapytanie i podejmuje decyzję, czy dostęp do danych będzie prowadzony poprzez skanowanie tabeli, czy przy wykorzystaniu indeksu. Rys. 6.6 Dostęp do danych przy korzystaniu z indeksów 146 Bazy danych Rodzaje indeksów Indeksy moŜna klasyfikować w róŜny sposób. My podzielimy indeksy na dwie grupy: • • indeksy grupowane (klastrowe), indeksy niegrupowane (nieklastrowe). Indeksy grupowane (ang. clustered) Indeks grupowany działa na podobnej zasadzie jak ksiąŜka telefoniczna. Zawiera strony szybkiego dostępu do danych (w ksiąŜce telefonicznej na początku znajduje się alfabetyczny spis mówiący o tym, na której stronie szukać nazwisk, firm czy instytucji zaczynających się na daną literę alfabetu). Strony te są ułoŜone w odwrócone drzewo i przechowują tylko ułoŜone alfabetycznie wartości indeksowanego pola oraz wskaźniki do stron znajdujących się w niŜszej warstwie drzewa. Na samym dole drzewa znajdują się strony zawierające posortowane wg indeksowanego pola dane (w ksiąŜce telefonicznej zawartość teŜ jest posortowana - wg nazwisk lub nazw firm czy instytucji). Przeszukiwanie indeksu odbywa się z góry na dół na następującej zasadzie: porównywana jest szukana wartość pola indeksowanego z wartościami zapisanymi (i posortowanymi) na stronach indeksu - jeśli znajdzie się wartość "większa" od wartości szukanej, wtedy następuje skok jeden poziom niŜej do strony wskazywanej przez ostatnią pozycję (na ostatnio sprawdzej stronie), która nie była "większa" od szukanej wartości. KaŜda pozycja na stronach zawiera wskaźnik do strony danych jeden poziom niŜej w hierarchii indeksu. Dzięki takiej strukturze przeszukiwane są tylko wybrane strony z danymi, nie zaś wszystkie strony zawierające dane z wybranej tabeli. W indeksie grupowanym strony z danymi wchodzą w skład indeksu i są posortowane po tym polu tabeli, które jest indeksowane. Wynika z tego, Ŝe na indeks grupowany naleŜy przeznaczyć więcej miejsca na dysku niŜ na same dane (posortowane dane + strony indeksu z najwyŜszych warstw). W związku z przedstawioną powyŜej zasadą działania indeksów nie wszystkie zapytania wykorzystują indeksy. Np. zapytanie (w MS SQL Server) SELECT imie, nazwisko FROM osoby WHERE nazwisko LIKE '%mar%' nie wykorzysta indeksu na polu nazwisko, poniewaŜ niemoŜliwe będzie porównanie wartości wzorca z wartościami na stronach indeksu. Bazy danych 147 Rys. 6.7 Indeks grupowany Indeks grupowany moŜe być dla danej tabeli tylko jeden (jednoznaczne sortowanie danych w indeksie). W MS SQL Server na wszystkich polach będących kluczami głównymi tabel są domyślnie zakładane indeksy grupowane. Indeksy niegrupowane (ang. nonclustered) Indeks niegrupowany działa na podobnej zasadzie jak indeks typowej w ksiąŜce (ale nie w telefonicznej). Indeks niegrupowany budowany jest na stronach danych, które nie są sortowane. Składa się z co najmniej dwu poziomów: poziomu niepomocniczego i poziomów pomocniczych. Na stronach poziomu niepomocniczego podobnie jak w przypadku indeksu grupowanego przechowywane są wartości indeksowanego pola ze wskaźnikami do poziomu niŜej w drzewie indeksu. Strony poziomu pomocniczego zwane teŜ liśćmi (ang. leaf) zawierają wskaźniki do konkretnych stron danych (które nie są posortowane). Wskaźnik taki zawiera następujące dane: ID pliku, numer strony, numer wiersza na stronie. Przeszukiwanie indeksu niegrupowanego odbywa się na podobnej zasadzie, jak w indeksie grupowanym. Po dojściu do poziomu pomocniczego następują skoki do stron danych (do konkretnych wierszy). Rys. 6.8 Indeks niegrupowany 148 Bazy danych Maksymalna ilość indeksów niegrupowanych w pojedynczej tabeli zaleŜy od SZBD. W MS SQL Server 2000 w jednej tabeli moŜna utworzyć maksymalnie 249 takich indeksów. Indeksy mają kluczowe znaczenie dla optymalizacji wydajności baz danych. Dobrze zaprojektowane indeksy mogą znacząco poprawić szybkość operacji przeszukiwania bazy danych (najczęściej wykonywana operacja i dotyczy największych ilości danych), ale źle zaplanowane mogą spowodować efekt odwrotny do poŜądanego. Dlatego naleŜy starannie zaplanować ich strukturę. Bazy danych 149 Operacje na indeksach Indeksy są tworzone najczęściej automatycznie dla kluczy głównych oraz dla pól, dla którym ma być wymuszona unikatowość. Indeksy moŜna teŜ tworzyć dla innych pól korzystając z polecenia języka SQL CREATE INDEX. PoniŜej podano przykład utworzenia indeksu grupowanego dla tabeli memeber dla pola lastname. Rys. 6.9 Przykład utworzenia indeksu przy uŜyciu języka SQL Indeksy mogą wymuszać unikatowość pól lub nie. Przykład deklaracja indeksu wymuszającego unikatowość pola title_no podano poniŜej. Po załoŜeniu takiego indeksu dodanie do tabeli rekordu o istniejącej juŜ wartości pola title_no nie będzie moŜliwe. Rys. 6.10 Wymuszanie unikatowości pola przez indeks Jak juŜ wspomnieliśmy, indeks moŜe teŜ być zakładany na kilku polach jednocześnie. PoniŜszy przykład pokazuje sposób definiowania unikalnego indeksu na polach isbn i copy_no jednocześnie. ZałoŜenie takiego indeksu spowoduje, Ŝe będzie moŜna wprowadzić do tabeli rekord o istniejącej juŜ wartości pola isbn oraz rekord o istniejącej wartości pola copy_no. Nie będzie natomiast moŜliwe wprowadzenie rekordu, w którym para wartości isbn i copy_no będzie się powtarzać. 150 Bazy danych Rys. 6.11 Przykład indeksu załoŜonego na kilku polach jednocześnie Bazy danych 151 Podsumowanie Dostep fizyczny do danych Optymalizacja dostepu Indeksy i ich zastosowanie Rodzaje indeksów Operacje na indeksach Indeksy stanowią waŜny mechanizm przyspieszający dostęp do danych zapisanych w bazie i wymuszający unikatowość danych. Z drugiej jednak strony obciąŜają dodatkowo system w czasie wykonywania operacji aktualizacji i wstawiania danych. Dlatego teŜ indeksy naleŜy stosować z rozwagą starannie planując, gdzie jakiego rodzaju indeksy załoŜyć. Decyzje o zakładaniu indeksów wynikają często ze specyfiki uŜytkowania bazy (np. kryteriów wyszukiwania) i często są podejmowane w czasie pierwszego okresu uŜytkowania bazy - okresu dostrajania systemu. 152 Bazy danych Laboratorium W tym ćwiczeniu stworzysz indeks, który zoptymalizuje zadane zapytanie. Bazy danych 153 Krok 1 - Przygotowanie tabeli ► ► ► ► ► ► ► Zaloguj się do maszyny wirtualnej ZBD jako uŜytkownik Administrator z hasłem P@ssw0rd. Kliknij Start. Z grupy programów Microsoft SQL Server 2005 uruchom SQL Server Management Studio. W oknie logowania kliknij Connect. Kliknij w menu głównym programu Management Studio na File. Kliknij Open - File. Odszukaj plik C:\Labs\Lab06\Indexes.sql i kliknij Open. Zaznacz fragment, który tworzy nową tabelę Sales.SalesOrderDetailCopy przez skopiowanie struktury i danych z tabeli Sales.SalesOrderDetail (patrz kod poniŜej). USE AdventureWorks GO SELECT * INTO Sales.SalesOrderDetailCopy FROM Sales.SalesOrderDetail ► Wciśnij F5, aby uruchomić zaznaczony kod. Krok 2 - Wykonanie zapytania bez optymalizacji ► ► Wciśnij kombinację klawiszy Ctrl+M, by włączyć pokazywanie graficznego planu wykonania zapytania. Zaznacz fragment, który włącza wyświetlanie statystyk wejścia / wyjścia (ilości odczytywanych stron danych) i wykonuje zapytanie do optymalizacji (patrz kod poniŜej). -- Statystyki i plan wykonania (Ctrl+M) SET STATISTICS IO ON -- Zapytanie do optymalizacji SELECT ProductID,OrderQty,UnitPrice FROM Sales.SalesOrderDetailCopy WHERE Unitprice > 100 AND OrderQty > 15 PowyŜsze zapytanie jest typowym zapytaniem wykonywanym w bazach danych. Zawiera klauzulę WHERE, która filtruje tabelę i ogranicza ilość wyświetlanych rekordów. Wynik zapytania nie jest tak istotny, jak odczyty w zakładkach Messages i Execution Plan (plan wykonania). W zakładce Messages sprawdź, Ŝe ilość odczytanych stron wynosi ponad 1400. Plan wykonania pokazuje zaś, Ŝe nastąpiło skanowanie tabeli, czyli przeczytanie jej wszystkich rekordów. 154 Bazy danych Krok 3 - Stworzenie indeksu ► Zaznacz fragment, który tworzy indeks (patrz kod poniŜej). -- Indeks z opcja INCLUDE CREATE INDEX ind_SOD_include ON Sales.SalesOrderDetailCopy(UnitPrice,OrderQty) INCLUDE (ProductID) ► Wciśnij F5, aby uruchomić zaznaczony kod. PowyŜszy kod tworzy indeks nieklastrowany na dwóch kolumnach (UnitPrice, OrderQty). Dodatkowo w strukturze indeksu na najniŜszym poziomie umieszczone zostają wartości z kolumny ProductID. Dzięki temu indeks pokrywa zapytanie, czyli w indeksie zawarte są wszystkie kolumny uŜyte w zapytaniu. Krok 4 - Wykonanie zapytania z optymalizacją ► Zaznacz fragment, który wykonuje ponownie zapytanie do optymalizacji (patrz kod poniŜej). SELECT ProductID,OrderQty,UnitPrice FROM Sales.SalesOrderDetailCopy WHERE Unitprice > 100 AND OrderQty > 15 ► Wciśnij F5, aby uruchomić zaznaczony kod. Tym razem zapytanie wykonane zostało z planem wykonania (patrz zakładka Execution Plan), który pokazuje, Ŝe nastąpiło przeszukanie indeksu (index seek). Ponadto w zakładce Messages zauwaŜysz, Ŝe ilość odczytanych stron zmalała niemal 10-ciokrotnie. ► Zaznacz i uruchom (F5 ) kod oznaczony komentarzem Clean-up, by usunąć utworzony indeks (wymagane do następnego ćwiczenia). Nie myśl, Ŝe najlepiej jest utworzyć indeks na wszystkich kolumnach tabeli jednocześnie. Taki indeks powoduje, Ŝe kaŜda modyfikacja danych wykonywana jest dłuŜej, a ponadto dane z tabeli są przechowywane w plikach danych w dwóch miejscach (czyli potrzebna jest dodatkowa przestrzeń dyskowa).