Politechnika Poznańska TWO Data: 2009-11-24 Nr Lab.: I Prowadzący: dr inż. Szymon Wilk Mateusz Jancy Joanna Splitter Zadanie: DZIELENIE RELACYJNE Rok: I Grupa: B Semestr: I Ocena: Cel zadania: Wykonać eksperyment polegający na porównaniu czasów wykonania poszczególnych zapytań języka SQL realizujących dzielenie relacyjne, wykorzystując dwie tabele T1 o kolumnach A zawierających wartości od 1 do 10 000 oraz B o wartościach od 1 do 100 połączonych w iloczyn kartezjański, tabelę T2 posiadającą kolumnę B z wartościami w 5 zestawach (100, 80, 60, 40, 20). Jako dodatkowy cel założyliśmy porównanie wyników wykonania zapytań dla 2 baz danych: MS SQL oraz Oracle. Zapytanie Q0: SELECT A FROM T1 WHERE B IN (SELECT B FROM T2) GROUP BY A HAVING COUNT(*) = (SELECT COUNT(*) FROM T2) Zapytanie Q1: SELECT DISTINCT x.a FROM T1 AS x WHERE NOT EXISTS ( SELECT * FROM T2 y WHERE NOT EXISTS ( SELECT * FROM T1 AS z WHERE (z.a=x.a) AND (z.b=y.b))) Zapytanie Q2: SELECT DISTINCT y.a, z.b INTO T3 FROM T1 AS y, T2 AS z WHERE NOT EXISTS ( SELECT * FROM T1 WHERE (T1.A = y.a) AND (T1.B=z.B)) SELECT DISTINCT A FROM T1 WHERE NOT EXISTS ( SELECT * FROM T3 WHERE (T3.A=T1.A))
Zapytanie Q3: SELECT DISTINCT x.a FROM T1 AS x WHERE (SELECT COUNT(*) FROM T2) = (SELECT COUNT(*) FROM T1, T2 WHERE (T1.A=x.A) AND (T1.B=T2.B)) 1. ŚRODOWISKO URUCHOMIENIOWE Procesor: Intel(R) Core 2 Duo CPU T6400 2.0 GHz Pamięć RAM: 4,00 GB Typ system: 32-bitowy System operacyjny: Windows Vista Home Premium BAZY DANYCH: Microsoft SQL Server 2008 wersja Express Oracle XE 10g 2. SZCZEGÓŁOWA ANALIZA ZAPYTAŃ MS SQL SERVER Wyniki pomiarów:
Czasy wykonania poszczególnych zestawów danych tabeli T2 dla każdej z prób: Zapytanie Q0: lp: numer pomiaru
Zapytanie Q1: lp: numer pomiaru Zapytanie Q2: lp: numer pomiaru Zapytanie Q3: lp: numer pomiaru
Czasy (średnie, minimalne, maksymalne, odchylenie standardowe) uzyskane podczas pomiarów wyliczone na podstawie 10 przeprowadzonych prób dla każdego z wariantów (zapytanie, próbka danych tabeli T2) Zbiór numer 1. lp: numer zapytania Zbiór numer 2. lp: numer zapytania Zbiór numer 3. lp: numer zapytania Zbiór numer 4.
lp: numer zapytania Zbiór numer 5. lp: numer zapytania Wyniki pomiarów dla poszczególnych zapytań zaprezentowane w formie średniego czasu realizacji zapytania. 3. PORÓWNANIE WYNIKÓW ZAPYTAŃ W KOTEKŚCIE 2 BAZ DANYCH ORAZ ROLA INDEKSÓW.. Dla przeprowadzenia testu na Oracle wymagane było stworzenie indeksu na tabeli T1. Brak indeksu powodował maksymalne użycie CPU oraz IO, ze względu na pełne skanowanie tabel (FULL TABLE SCAN) dla wszystkich tabel użytych w zapytaniach Q1, Q2,
Q3. Czas określony przez polecenie explain plan dla zapytania wykonanego na tabelach bez indeksów to 3548041 sekund (ok. 985 godzin). Explain plan umieszcza informacje w tabeli plan_table [2]. Analiza na przykładzie Q1: Po stworzeniu indeksu dla T1(A), czas zwrócony przez explain plan wynosił - 24389s. Po stworzeniu dodatkowego indeksu T1(B) przewidywany czas zapytania nie uległ zmianie (nadal wykorzystywany był tylko indeks dla kolumny A). Podobnie było w przypadku indeksu dla T2(B), w tym wypadku Oracle optimizer ze względu na mały rozmiar tabeli wybrał FULL TABLE SCAN zamiast indeksu. Kolejne skrócenie czasu zapytania pojawiło się dopiero po stworzeniu indeksu T1(A,B) - 18375s. Pomimo, że przewidywane przez optimizer czasy są dalekie od rzeczywistości, pozwalają jednak na porównanie rzędu wielkości różnicy między zapytaniem z i bez indeksów. MSSQL radzi sobie w przypadku tych 3 zapytań zdecydowanie lepiej, ponieważ używa Index Spool [1], który jest tymczasowym indeksem używanym i tworzonym w czasie wywołania zapytania na bazie danych. Ten tymczasowy indeks daje zdecydowaną przewagę w porównaniu do Oracle, który dopiero po manualnym stworzeniu indeksów jest w stanie wykonać zapytania w rozsądnym czasie. Czas stworzenia indeksów T1(A) - 14.857s, T1(B) - 2.6s, T2(B) - 0.189s, T1(A,B) - 3.117s. Po wprowadzeniu indeksów, pierwsze dane zapytania Q1 zostały zwrócone po ~60 sekundach. Execution plany dla Oracle: Bez utworzonych indeksów: Utworzony indeks: T1(A) Utworzone indeksy: T1(A), T1(B)
Utworzone indeksy: T1(A), T1(B), T2(B) Utworzone indeksy: T1(A), T1(B), T1(A,B), T2(B) Execution plan dla MSSQL (bez wykorzystania indeksów): StmtText --Stream Aggregate(GROUP BY:([x].[A])) --Nested Loops(Left Anti Semi Join, OUTER REFERENCES:([x].[A])) --Sort(ORDER BY:([x].[A] ASC)) --Table Scan(OBJECT:([two-bd].[dbo].[T1] AS [x])) --Row Count Spool --Hash Match(Left Anti Semi Join, HASH:([y].[B])=([z].[B]), RESIDUAL:([two-bd]. [dbo].[t1].[b] as [z].[b]=[two-bd].[dbo].[t2].[b] as [y].[b])) --Table Scan(OBJECT:([two-bd].[dbo].[T2] AS [y])) --Index Spool(SEEK:([z].[A]=[two-bd].[dbo].[T1].[A] as [x].[a])) --Table Scan(OBJECT:([two-bd].[dbo].[T1] AS [z])) [1] http://msdn.microsoft.com/en-us/library/ms189611.aspx [2] http://download.oracle.com/docs/cd/b28359_01/server.111/b28320/statviews_5127.htm W celu przeprowadzenia badania porównującego wyniki zapytań dla Oracle I MS SQL w
każdej bazie danych utworzone zostały indeksy: T1(A), T1(B), T2(B). Porównanie wykonane zostało na podstawie próbki danych T2_B_COUNT = 100. Czas przedstawiony poniżej to średnia czasu wykonania 10 zapytań w sekundach.
ORACLE MS SQL Q0 0,702 2,492 Q1 59,569 13,097 Q2 78,452 175,850 Q3 3,136 3,670
4. WNIOSKI 1. Czas realizacji wszystkich zapytań maleje w miarę jak pomniejszamy ilość rekordów tabeli T2. (Dobry przykład stanowi wynik zapytań Q0, w zapytaniu Q1 natomiast wystąpiło dziwne przekłamanie polegające na zrównaniu się czasów wykonania dla zestawów danych 1 oraz 5). 2. Zapytania Q0 oraz Q3 posiadają niezależnie od testowego zestawu danych zdecydowanie lepsze czasy realizacji w porównaniu do zapytań Q1 i Q2. 3. Najbardziej efektywny sposób realizacji dzielenia relacyjnego niezależnie od zestawu danych oraz silnika baz danych stanowi Zapytanie Q0, z kolei najmniej efektywne to Q2. 4. Baza danych Oracle kompletnie nie radzi sobie z zapytaniami typu SELECT DISTINCT FROM.. SUBQUERY..SUBQUERY w przypadku gdy nie utworzymy indeksów. (Q1, Q2, Q3). 5. W przypadku bazy danych MS SQL rola rzeczywistych indeksów nie wydaje się zbyt wielka czasy różnią się nieznacznie (jednak jest to zapewne wynikiem tymczasowych indeksów stosowanych w przypadku tej bazy danych) 6. Biorąc pod uwagę najefektywniejsze zapytanie Q0, którego użylibyśmy na podstawie przeprowadzonego badania w celu realizacji dzielenia relacyjnego Oracle okazuje się znacznie wydajniejszy czas wykonania zapytania jest ok. 3,5 razy szybszy od czasu jaki osiąga MS SQL niezależnie od istnienia indeksów w bazie danych.