Ogólnie

 

W SQL specyyfikujemy co ma być zrobione a nie w jaki sposób. System zarządzania bazą danych wybiera najbardziej optymalny sposób wyszukiwania. Zapytania są realizowane w następujący sposób:

  • Gdy specyfikowana kolumna jest jednocześnie indeksem głównym, wtedy wyszukiwanie jest przeprowadzane bezpośrednio na tej kolumnie
  • Gdy kolumna nie jest indeksem, wtedy następuje wyszukiwanie klucza głównego i dopiero wg niego wyszukiwane są odpowiednie rekordy w bazie danych
Indeks zdefiniowany na pliku jest dodatkową strukturą fizyczną, której celem jest przyspieszenie wykonywania operacji, które nie są wystarczająco efektywnie wspierane przez podstawowe organizacje plików i struktury logiczne danych. Indeksy są zakładane na pojedynczych atrybutach lub zbiorach atrybutów relacji. Atrybuty te noszą nazwę atrybutów indeksowych. Indeks jest uporządkowanym plikiem rekordów indeksu (ang. data entry) o stałej długości. Rekordy indeksu zawierają dwa pola: klucz reprezentujący jedną z wartości występujących w atrybutach indeksowych relacji oraz wskaźnik do bloku danych zawierający krotkę, której atrybut indeksowy równy jest kluczowi.

Stosowanie indeksów

 

W bibliotekach istnieją specjalne katalogi książek, służące do szybkiego odszukania wybranej pozycji. Mogą one być poukładane na różne sposoby, np. alfabetycznie wg autora lub tytułu książki. Po odszukaniu książki w katalogu, możesz odczytać nr regału i półki gdzie się książka znajduje, przez co musisz już tylko przejrzeć ksiązki na jednej półce (np. 30 sztuk) aby znaleźć tą potrzebną, zamiast wszystkich zgromadzonych książek (np. 30 tysięcy).

Na podobnej zasadzie działają indeksy w bazie danych - pozwalają na szybkie odszukanie wymaganych danych, przez co zapytania będą się wykonywać znacznie szybciej. Podam jeden przykład z którym miałem osobiście do czynienia: zapytanie wybierało dane z ponad 10 tabel, z których największa miała nieco ponad milion rekordów. Pracowało ono ponad 5 minut. Po założeniu indeksu na tej największej tabeli, czas wykonywania zapytania skrócił się do pół minuty (przyśpieszenie ponad 10 razy). Zatem jest o co walczyć :).

Indeksy mogą być różnych typów. Można je podzielić na indeksy zakładane na jedną kolumnę, lub na wiele kolumn równocześnie (to jest coś innego niż posiadanie wielu indeksów na pojedynczych kolumnach - więcej szczegółów później). Innym podziałem jest podział na indeksy unikalne (każda wartość w indeksie z indeksem musi być inna; jest to stosowane np. do zapewnienia unikalności kluczy głównych), oraz "normalne" (czyli nie unikalne - wartości w indeksie mogą się powtarzać. To jest najczęstszy przypadek).

Rodzaje indeksów

 

  • Rodzaje indeksów ze względu na charakterystykę atrybutu indeksowego:
    • Indeks podstawowy (primary index) – założony na atrybucie porządkującym unikalnym.
      Indeks podstawowy jest indeksem rzadkim ponieważ nie wszystkie rekordy pliku danych posiadają rekordy indeksowe. Rekord indeksowy indeksu podstawowego dla wartości X zawiera adres bloku danych, w którym znajduje się rekord danych z wartością atrybutu indeksowego równą X.
    • Indeks zgrupowany (clustering index) – założony na atrybucie porządkującym nieunikalnym.
      Indeks zgrupowany jest również indeksem rzadkim ponieważ nie wszystkie rekordy pliku danych posiadają rekordy indeksowe. Rekord indeksowy indeksu zgrupowanego dla wartości X zawiera adres bloku danych, w którym znajduje się pierwszy rekord danych z wartością atrybutu indeksowego równą X. Taka organizacja pliku powoduje problemy z wstawianiem i rekordów, ponieważ porządek rekordów po wstawieniu musi pozostać zachowany.
    • Indeks wtórny (secondary index) – założony na atrybucie nieporządkującym.
      Indeks wtórny jest również uporządkowany. Jest on zakładany na atrybucie indeksowym pliku danych, który nie jest atrybutem porządkującym tego pliku. Każdy rekord pliku danych posiada swój odpowiednik w rekordzie indeksu. Stąd, indeks wtórny jest indeksem gęstym. Rekord indeksu wtórnego składa się z dwóch pól: wartości pola indeksowego i wskaźnika albo do rekordu albo do bloku danych zawierającego ten rekord.

  • Rodzaje indeksów ze względu na wskazanie do pliku danych:
    • Indeksy gęste (ang. dense) - posiada rekord indeksu dla każdego rekordu indeksowanego pliku danych
    • Indeksy rzadkie (ang. sparse) - posiada rekordy tylko dla wybranych rekordów indeksowanego pliku danych

  • Rodzaje indeksów ze względu na liczbę poziomów:
    • Indeksy jednopoziomowe - jeden plik indeksu dla jednego pliku danych
    • Indeksy wielopoziomowe – indeks do indeksu

  • Rodzaje indeksów ze względu na strukturę:
    • Indeksy bitmapowe
      Jest on najlepszy w przypadku niskiej selektywności. Dla przykładu kolumna z wartościami 1 lub 0 nadaje się do założenia na niej indeks bitmapowy. Informacje przechowywane w takim indeksie są w postaci mapy bitów dla każdej wartości występującej w danej kolumnie. Główną zaletą takich indeksów jest to, że bardzo łatwo takie mapy bitów można łączyć. Przykładem takiego efektywnego wykorzystania indeksów jest sytuacja, kiedy kilka wartości o malej selektywności może być połączonych w złączenie o wysokiej selektywności.
    • B-drzewa
      Stosuje się strukturę podobna do odwróconego drzewa. Na samej górze tego drzewa znajduje się korzeń, poniżej są poziomy z gałęziami, a na samym dole znajdują się liście zawierające informacje o położeniu rekordu bądź rekordów w tabeli.

Podział:
  • ze względu na liczbę atrybutów indeksowych w kluczu: indeksy zwykłe i indeksy złożone
  • ze względu na unikalność wartości klucza: indeksy unikalne i indeksy nieunikalne
  • ze względu na kolejność wartości klucza: indeksy zwykłe i indeksy odwrócone
  • ze względu na sposób składowania: indeksy nieskompresowane i indeksy skompresowane
  • ze względu na zastosowania: indeksy funkcyjne i bitmapowe indeksy połączeniowe

Ogólne zasady optymalizacji

 

  • unikać za wszelką cenę zagnieżdżania selectów. Jest to strasznie wolne
  • starać się ustalić taką kolejność złączeń i warunków (where warunek), aby jak najszybciej ograniczać rozmiar przetwarzanego zbioru (tzn. najpierw wykonać where na liczącej 100K wierszy tabelce, a potem wynik złączać z drugą a nie na odwrót)
  • jeśli to możliwe – używać indeksów tam gdzie często robimy sortowanie czy wyszukiwanie po określonej wartości. Jeśli baza oferuje kilka rodzajów indeksów – postarać się wybrać ten właściwy (tu wszystko zależy już od bazy i danych)
  • jeśli to możliwe, prawidłowo dobierać sposób przechowywania danych do danych (b-drzewa, clustery itd). Tu wszystko zależy od bazy danych
  • unikać użycia LIKE jak ognia. Jeśli trzeba, to zamiast %(dowolny ciąg znaków) używać _(dowolny jeden znak) tam gdzie się da
  • unikać podzapytań – wolne
  • firmowy optymalizator wiele rzeczy zrobi lepiej od nas, a innych nie zrobi w ogóle