• Nie Znaleziono Wyników

Systemy zarządzania bazami danych

N/A
N/A
Protected

Academic year: 2021

Share "Systemy zarządzania bazami danych"

Copied!
57
0
0

Pełen tekst

(1)

Systemy zarządzania bazami danych

6. Optymalizacja zapytań

(2)

--> Generowanie i wybór planu Zapytanie

Generuj Plany

Oczyść x x Oszacuj koszty

Koszty Wybierz

Optymalizacja zapytań

Wybierz Minimum

(3)

Generując plany weź pod uwagę:

• Przekształcenia zapytania w algebrze relacji (np. porządek złączeń)

• Użycie istniejących indeksów

• Zbudowanie nowych indeksów

• Sortowanie na użytek zapytania

(4)

Szczegóły implementacyjne

• Algorytmy złączania

• Zarządzanie pamięcią

• Przetwarzanie równoległe

(5)

Szacowanie kosztów we/wy

• Liczba bloków dyskowych, które trzeba przeczytać (i/lub zapisać) aby

zrealizować plan zapytania

– Zapisy potrzebne np. do realizacji

wielofazowego sortowania zewnętrznego

(6)

Szacowanie wymaga parametrów

B(R) = liczba bloków z krotkami relacji R f(R) = liczba krotek R w jednym bloku M = liczba dostępnych ramek pamięci HT(i) = liczba poziomów indeksu i

LB(i) = liczba bloków z liśćmi indeksu i

• Jakich operacji są to koszty?

(7)

Indeks pogrupowany

• Indeks, w którym pozycje indeksu są w takim samym fizycznym porządku jak rekordy

na Aind.

10 15 17 19 35 A

(8)

Różne znaczenia pogrupowania

• Grono (cluster)

…..

• Relacja pogrupowana (clustered)

…..

• Indeks pogrupowany (clustering)

R1 R2 S1 S2 R3 R4 S3 S4

R1 R2 R3 R4 R5 R5 R7 R8

(9)

R1 ⋈ R2 po wspólnym atrybucie C

T(R1) = 10.000 T(R2) = 5.000

S(R1) = S(R2) = 1/10 bloku

Dostępna pamięć = 101 bloków Miara: liczba operacji we/wy

(10)

Ostrożnie

• To może nie być najlepszy sposób szacowania:

– Ignorujemy koszt przetwarzania przez procesor

– Ignorujemy synchronizację

– Ignorujemy możliwości równoległej pracy procesora i dysku (np. DMA)

(11)

Możliwości

• Transformacje: R1 ⋈ R2, R2 ⋈ R1

– Która relacja prowadząca?

– Jaka kolejność złączeń?

• Algorytmy złączenia:

– Iteracyjne (nested loops)

– Przez scalanie (sort-merge join)

– Iteracyjne z indeksem (index nested loops)

(12)

Złączenie iteracyjne

for each r  R1 do

for each s  R2 do

if r.C = s.C then output <r,s>

(13)

Przez scalanie (przykład)

i R1{i}.C R2{j}.C j

1 10 5 1 2 20 20 2 3 20 20 3 4 30 30 4 5 40 30 5 50 6 52 7

(14)

Przez scalanie

(1) Jeśli R1 i R2 nie posortowane po C, posortuj je (2) i  1; j  1;

while (i  T(R1))  (j  T(R2)) do

if R1{ i }.C = R2{ j }.C then outputTuples else if R1{ i }.C > R2{ j }.C then j  j+1 else if R1{ i }.C < R2{ j }.C then i  i+1

(15)

Procedura outputTuples

while (R1{ i }.C = R2{ j }.C)  (i  T(R1)) do [ jj  j;

while (R1{ i }.C = R2{ jj }.C)  (jj  T(R2)) do [ output <R1{ i }, R2{ jj }>;

jj  jj+1 ] i  i+1 ]

(16)

for each r R1 do

[ X index (R2, C, r.C) for each s X do

output <r,s> ]

Zakładamy istnienie indeksu

na R2.C

X  index(R, A, W)

wówczas: X = zbiór krotek R o atrybucie A równym W

Iteracyjne z indeksem

(17)

– Funkcja haszująca h, przeciwdziedzina 0  k – Kubełki dla R1: G0, G1, ... Gk

– Kubełki dla R2: H0, H1, ... Hk

(1) Rozrzuć krotki R1 do kubełków G (hasz na C) (2) Rozrzuć krotki R2 do kubełków H (hasz na C) (3) Dla każdego i = 0, 1, 2,..., k

dopasuj krotki z kubełków Gi i Hi

Haszowane

(18)

Prosty przykład: parzyste/nieparzyste

R1 R2 Kubełki

2 5 Parzyste:

4 4 R1 R2

3 12 Nieparzyste:

5 3

8 13

9 8 11

2 4 8 4 12 8 14

3 5 9 5 3 13 11

(19)

Czynniki wpływające na wydajność

• Czy krotki relacji są trzymane razem fizycznie (ciągłe)?

• Czy relacje są posortowane po atrybucie złączenia?

• Czy są dostępne indeksy?

• Jak selektywne jest zapytanie?

(20)

Złączenie iteracyjne R1 ⋈ R2

• Relacje nieciągłe

T(R1) = 10.000 T(R2) = 5.000 S(R1) = S(R2) =1/10 bloku

M = 101 bloków Koszt: dla każdej krotki R1:

[Odczyt krotki + odczyt całej R2]

Łącznie =10.000 [1+5000]=50.010.000

Ma sak ra

(21)

Czy da się lepiej?

• Użyjmy naszych umysłów

• Żeby wykorzystać dostępną pamięć

(1) Wczytaj 100 bloków R1

(2) Wczytaj całą R2 (używając 1 bloku) i złącz (3) Powtarzaj do wyczerpania R1

(22)

• Dla każdego fragmentu R1:

Odczyt fragmentu: 1000 Odczyt R2: 5000

6000

Łącznie = 10.000 x 6000 = 60.000 1.000

Koszty?

Am nes tia

(23)

Czy można jeszcze lepiej?

 Odwróć kolejność: R2 ⋈ R1

Łącznie = 5000 x (1000 + 10.000) = 1000

5 x 11.000 = 55.000

(24)

• Relacje ciągłe

Złączenie iteracyjne R1 ⋈ R2

Koszt

• Dla każdego fragmentu R2:

Odczyt fragmentu: 100 Odczyt R1: 1000 1100

Łącznie= 5 fragmentów x 1100 = 5500

(25)

Złączenie przez scalanie

• R1, R2 posortowane po C; ciągłe

Pamięć

R1 R2

…..

…..

R1

R2

Łączny koszt: Odczyt R1 + Odczyt R2

(26)

• R1, R2 nieposortowane, ale ciągłe

• Trzeba je posortować

• Jak?

Złączenie przez scalanie

(27)

Sortowanie przez scalanie

(i) Dla każdego 100-blokowego fragmentu R:

- Przeczytaj fragment - Posortuj go w pamięci - Zapisz go na dysk

posortowane fragmenty

R1

R2 ...

(28)

(ii) Przeczytaj fragmenty, scal i wypisz

Posortowany

plik Pamięć

posortowane fragmenty

...

...

(29)

Koszt sortowania

• Każda krotka jest odczytywana, zapisywana odczytywana, zapisywana

• Koszt sortowania R1: 4 x 1000 = 4.000

• Koszt sortowania R2: 4 x 500 = 2.000

(30)

Sortowanie przez scalanie

R1,R2 ciągłe ale nieposortowane

Łączny koszt = sortowanie + scalanie = 6000 + 1500 = 7500

Ale: Koszt złączenia iteracyjnego = 5.500

Złączenie przez scalanie się nie opłaca!

(31)

Ale: R1 = 10.000 bloków ciągłe

R2 = 5.000 bloków nieposortowane Iteracyjnie: 5000 x (100+10.000) = 50x10.100

100

= 505.000

Przez scalanie: 5(10.000+5.000) = 75.000 Złączenie przez scalanie wygrywa!

(32)

Pamięć potrzebna do sortowania

Np. Załóżmy że mamy 10 bloków 10

...

100 fragmentów  do złączenia potrzebujemy 100 bloków!

R1

(33)

W ogólności

• Liczba ramek pamięci: k

• Wielkość relacji: x bloków

• Liczba fragmentów = (x/k)

• Wielkość fragmentu = k

L. fragmentów < L. ramek przy scalaniu więc... (x/k)  k

(34)

W naszym przykładzie

• R1 ma 1000 bloków, k  31.62

• R2 ma 500 bloków, k  22.36

• Potrzeba co najmniej 32 ramek

(35)

Czy da się jeszcze poprawić scalanie?

• Czy naprawdę potrzebujemy całkowicie posortowanych relacji?

R1

R2

Złączenie

Posortowane

(36)

Koszt poprawionego algorytmu

Odczyt R1 + Zapis posortowanych frag. R1 + Odczyt R2 + Zapis posortowanych frag. R2 + scalenie

= 2000 + 1000 + 1500 = 4500

• Jakie są wymagania względem pamięci?

(37)

Iteracyjne z indeksem

• Załóżmy istnienie indeksu na R1.C (dwupoziomowego)

• Załóżmy, że R2 jest ciągła, nieposortowana

• Załóżmy, że indeks na R1.C mieści się w pamięci

(38)

Odczyt R2: 500

dla każdej krotki R2:

- Wyszukiwanie w indeksie (za darmo) - Odczyt każdej krotki R1 wskazanej przez indeks to koszt 1

Koszt iteracyjnego z indeksem

(39)

Ile jest pasujących krotek?

(a) Jeśli R1.C to klucz, R2.C to klucz obcy, to spodziewana liczba = 1

(b) Jeśli V(R1,C) = 5000, T(R1) = 10.000 (z założeniem rozkładu równomiernego) spodziewana liczba = 10.000/5.000 = 2

(40)

(c) Jeśli DOM(R1, C)=1.000.000 T(R1) = 10.000

gdy rozkład równomierny w dziedzinie Spodziewana = 10,000 = 1

liczba 1.000.000 100

Ile jest pasujących krotek?

(41)

Koszt iteracyjnego z indeksem

(a) Łącznie = 500+5000(1)1 = 5,500 (b) Łącznie = 500+5000(2)1 = 10,500 (c) Łącznie = 500+5000(1/100)1=550

(42)

Gdy indeks nie mieści się pamięci?

• Załóżmy, że indeks na R1.C ma 201 bloków

• Trzymaj korzeń + 99 liści w pamięci

• Średni koszt każdego wyszukiwania to:

E = (0)99 + (1)101  0,5 200 200

(43)

= 500+5000 [Wyszukiwanie + pobierz rekordy]

= 500+5000 [0,5+2]

= 500+12.500 = 13.000 (przypadek b) Przypadek (c)

= 500+5000[0,5  1 + (1/100)  1]

= 500+2500+50 = 3050

Koszt łączny (z wyszukiwaniem)

(44)

Dotychczas

Iteracyjne R2

R1 55000 (najlepszy) Scalanie _______

Sort+Scalanie _______

Z indeksem na R1.C _______

Z indeksem na R2.C _______

Iteracyjne R2

R1 5500

Scalanie 1500

Sort+Scalanie 7500  4500

Z indeksem na R1.C 5500  3050  550 Z indeksem na R2.C ________

ciągłenie-ciągłe

(45)

• R1, R2 ciągłe (nie-posortowane)

Użyj 100 kubełków

Odczytaj R1, haszuj + zapisz kubełki R1

Haszowane

... ... 100

(46)

->Tak samo dla R2

->Przeczytaj kubełek R1; zbuduj w pamięci tab.hasz.

->Przeczytaj odpowiedni kubełek R2 + złącz haszem

R1

R2

...

R1

Pamięć

...

->Powtórz dla wszystkich kubełków

(47)

Koszt

Kubełkowanie Odczyt R1 + zapis Odczyt R2 + zapis Scalanie: Odczyt R1, R2

Koszt łączny = 3 x [1000+500] = 4500

Uwaga: to jest tylko oszacowanie, ponieważ

(48)

Wymaganie pamięciowe

Rozmiar kubełka dla R1 = (x/k)

k = liczba ramek pamięci x = liczba bloków R1

Więc? (x/k) < k

k > x potrzeba k+1 ramek

(49)

Sztuczka: trzymaj niektóre kubełki w RAM

Np., k’=33 kubełki R1 = 31 bloków trzymaj 2 w RAM

pamięć G0 G1

wej.

...

31

33-2=31

R1

Użycie pamięci:

G0 31 ramek

G1 31 ramek

Wyjście 33-2 ramek Odczyt R1 1

Łącznie 94 ramek Zostało jeszcze 6 ramek!

(50)

Następnie: Kubełkowanie R2

– Kubełki R2 =500/33= 16 bloków

– Dwa z kubełków R2 od razu łączone z G0,G1

pamięć G0 G1

wej.

...

16

33-2=31

R2

...

31

33-2=31

Kubełki R2 Kubełki R1

(51)

Ostatecznie: Scal pozostałe kubełki

– Dla każdej pary kubełków:

• Wczytaj jeden z nich w całości do pamięci

• Scal z drugim z nich pamięć

Gi wyj.

...

16

33-2=31

wynik

...

31

33-2=31

Kubełki R2 Kubełki R1

cały kubełek R2

jedna ramka R1

(52)

Koszt hybrydowego haszowanego

• Kubełkowanie R1 = 1000+3131=1961

• Kubełkowanie R2, zapisujemy tylko 31 kubełków, więc 500+3116=996

• Scalanie kubełków (2 już z głowy):

odczyty 3131+3116=1457

• Łącznie = 1961+996+1457 = 4414

(53)

Ile kubełków trzymać w pamięci?

pamięć G0 G1

R1 wej.

pamięć

G0 R1 wej.

czy ?

(54)

Kolejna sztuczka dla haszowanego

• Do kubełków zapisuj tylko pary

<wartość,wskaźnik>

= Utworzenie indeksu haszowanego w locie

• Dopiero gdy znajdzie się para

pasujących krotek, trzeba ściągnąć z dysku krotki

(55)

• Założenia:

– 100 par <wartość,wskaźnik> w bloku

– Spodziewana liczba krotek wynikowych = 100

• Zbuduj tablicę haszującą dla R2 w pamięci 5000 krotek  5000/100 = 50 bloków

• Odczytaj R1 i scalaj

• Odczytaj ~ 100 krotek R2

Łączny koszt = Odczyt R2: 500 Odczyt R1: 1000 Pobierz krotki: 100

(56)

Dotychczas

Iteracyjne 5500

Scalanie 1500

Sort+scalanie 7500

Indeks na R1.C 5500  550 Indeks na R2.C _____

Zbuduj indeks na R1.C _____

Zbuduj indeks na R2.C _____

Haszowane 4500+

sztuczka,R1 prow. 4414 sztuczka,R2 prow. _____

Haszowane, wskaźniki 1600

ciągłe

(57)

Podsumowanie

• Iteracyjne dobre dla „małych” relacji (w porównaniu z wielkością pamięci)

• Dla złączenia równościowego, gdy relacje nie są posortowane i nie ma indeksów,

haszowane zwykle najlepsze

• Przez scalanie dobre dla złączeń nie- równościowych (np., R1.C > R2.C)

• Jeśli relacje już posortowane, użyj scalania

• Jeśli są indeksy, mogą być użyteczne (zależy to od selektywności – spodziewanego

Cytaty

Powiązane dokumenty

(4) Ti może założyć zamek X,SIX,IX na węzeł Q tylko wtedy, gdy rodzic(Q) ma zamek IX lub SIX założony przez transakcję Ti. (5) Ti zakłada

• Otwarcie połączenia z bazą danych jest drogie, ale wielokrotne użycie tanie. – Używaj

– Brak promocji zamków w Oracle; Parametry DB2 ustawione, żeby nie było promocji zamków; brak takiej kontroli w SQL Server. – Dual Xeon (550MHz,512Kb), 1Gb

– Zapis do pamięci podręcznej: transfer kończy się, gdy dane znajdą się w pamięci podręcznej sterownika. • Baterie gwarantują zapis przy

• Punkt kontrolny (częściowy zrzut brudnych strona na dysk) odbywa się w stałych odstępach lub po zapełnieniu dziennika:. – Wpływa na wydajność bazy + Pozwala

– Jeśli często odczytuje się adres dostawcy na podstawie numeru zamówionej części, to schemat 1 jest dobry.. – Jeśli jest wiele dodawanych wiele zamówień, schemat 1

• Indeks niepogrupowany jest dobry, gdy używające go zapytania zwracają znacznie mniej rekordów niż jest stron w tabeli. •

• DISTINCT jest zbędny, ponieważ ssnum jest kluczem w employee, więc też i kluczem w podzbiorze relacji employee...