Rok akademicki 2013/2014

Politechnika Warszawska Wydziaª Elektroniki i Technik Informacyjnych Instytut Informatyki

PRACA DYPLOMOWA IN›YNIERSKA Katarzyna Kwa±niewska Partycjonowanie w Oracle Database 11gR2, ocena potencjalnych i rzeczywistych korzy±ci z ró»nych metod partycjonowania danych i indeksów

Opiekun pracy: dr in». Michaª Rudowski

Ocena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

...................................... Podpis Przewodnicz¡cego

Komisji Egzaminu Dyplomowego

Specjalno±¢:

Informatyka  In»ynieria systemów informatycznych

Data urodzenia:

30 kwietnia 1991 r.

Data rozpocz¦cia studiów:

1 pa¹dziernika 2010 r.

›yciorys Urodziªam si¦ 30 kwietnia 1991 roku w Warszawie. W latach 2007-2010 ucz¦szczaªam do II Liceum Ogólnoksztaªc¡cego imienia Stefana Batorego w Warszawie do klasy o prolu matematyczno-zyczno. W 2010 roku rozpocz¦ªam studia na Wydziale Elektroniki i Technik Informacyjnych Politechniki Warszawskiej, na kierunku Informatyka. Od semestru zimowego 2012/2013 moj¡ specjalno±ci¡ jest In»ynieria Systemów Informatycznych. W lecie 2013 roku (od lipca do wrze±nia) odbyªam praktyki w rmie Samsung Electronics Polska Sp.z o.o. Poza zainteresowaniami technicznymi do swoich pasji zaliczam podró»owanie, muzyk¦ oraz sport.

.................................... podpis studenta

Egzamin dyplomowy Zªo»yªa egzamin dyplomowy w dn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Z wynikiem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Ogólny wynik studiów . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Dodatkowe wnioski i uwagi Komisji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.................................................................................

Streszczenie Tematem pracy jest partycjonowanie tabel i indeksów w Oracle Database 11gR2. Partycjonowanie jest dodatkow¡ opcj¡ dost¦pn¡ dla bazy danych Oracle Database Enterprise Edition. Jest to pot¦»ny mechanizm, szczególnie przydatny przy zarz¡dzaniu du»¡ ilo±ci¡ danych. Partycjonowanie mo»e znacz¡co uªatwi¢ administrowanie baz¡ oraz pozwoli¢ na zwi¦kszenie wydajno±ci, rozumianej gªównie jako szybko±¢ dost¦pu do danych. W pierwszych rozdziaªach opisaªam mo»liwe sposoby partycjonowania oraz dokonaªam analizy potencjalnych korzy±ci wynikaj¡cych z ich zastosowania. Nast¦pnie przedstawiªam wyniki bada« efektywno±ci partycjonowania i jego wpªywu na czas wykonywania polece«: SELECT w zale»no±ci od rozmiaru danych.

Sªowa kluczowe: Oracle,

Partycjonowanie, Baza Danych, Tabele, Indeksy.

Partitioning in Oracle Database 11gR2, assessment of potential and actual benets of the various methods of tables and indexes partitioning The subject of this work is partitioning tables and indexes in Oracle Database 11gR2. Partitioning is an additional option available for Oracle Database Enterprise Edition. It is a powerful mechanism particularly useful when managing large volumes of data. Partitioning can simplify database administration, improve availability and signicantly increase productivity, understood primarily as a data access speed. In rst chapters, I described the possible ways of partitioning and made an analysis of potential benets arising from their usage. Then I presented results of study concerning partitioning eectivness and its eect on the performance of SELECT queries, depending on the size of the manipulated data.

Key words: Oracle,

Partitioning, Database, Tables, Indexes.

Spis tre±ci

1 Wst¦p

5

1.1

Wprowadzenie do tematu pracy

. . . . . . . . . . . . . . . . . . . . .

6

1.2

Cel i motywacja pracy

. . . . . . . . . . . . . . . . . . . . . . . . . .

7

1.3

Ukªad i zakres pracy

. . . . . . . . . . . . . . . . . . . . . . . . . . .

7

2 Opcja partycjonowania w Oracle Database 2.1

2.2

2.3

Korzy±ci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9

2.1.1

Efektywne administrowanie

. . . . . . . . . . . . . . . . . . .

9

2.1.2

Bezpiecze«stwo, dost¦pno±¢

. . . . . . . . . . . . . . . . . . .

10

2.1.3

Przycinanie partycji (ang. partitioning pruning)

. . . . . . . .

10

2.1.4

Zª¡czenia partycji (ang. partition-wise joins) . . . . . . . . . .

11

2.1.5

Zrównoleglenie, skalowalno±¢ . . . . . . . . . . . . . . . . . . .

11

Metody partycjonowania do wersji Oracle 10g

. . . . . . . . . . . . .

12

2.2.1

Partycjonowanie Zakresowe (ang. Range Partitioning) . . . . .

12

2.2.2

Partycjonowanie Mieszaj¡ce (ang. Hash Partitioning)

. . . . .

13

2.2.3

Partycjonowanie Listowe (ang. List Partitioning) . . . . . . . .

14

2.2.4

Partycjonowanie Dwupoziomowe (ang. Composite Partitioning) 15

Nowe w 11g metody i wªa±ciwo±ci partycjonowania

. . . . . . . . . .

17

2.3.1

Partycjonowanie Interwaªowe (ang. Interval Partitioning) . . .

17

2.3.2

Partycjonowanie Systemowe (ang. System Partitioning) . . . .

18

2.3.3

Partycjonowanie Referencyjne (ang. Reference Partitioning)

.

19

2.3.4

Partycjonowanie na Bazie Kolumny Wirtualnej (ang. Virtual Column Based Partitioning) . . . . . . . . . . . . . . . . . . .

21

Partycjonowanie Dwupoziomowe w Oracle 11gR2

. . . . . . .

21

. . . . . . . . . . . . . . . . . . . . . . . .

22

2.4.1

Lokalny Indeks Partycjonowany . . . . . . . . . . . . . . . . .

22

2.4.2

Indeks Globalny . . . . . . . . . . . . . . . . . . . . . . . . . .

23

Perspektywy dotycz¡ce partycji tabel i indeksów . . . . . . . . . . . .

26

2.3.5 2.4

2.5

9

Partycjonowanie indeksów

3 ‘rodowisko testów opcji partycjonowania

29

3.1

Cel i zakres testów

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

29

3.2

Opis ±rodowiska testowego . . . . . . . . . . . . . . . . . . . . . . . .

29

1

3.3

3.4

3.5

Relacyjny model danych

. . . . . . . . . . . . . . . . . . . . . . . . .

31

3.3.1

Partycjonowanie referencyjne (orem1) . . . . . . . . . . . . . .

34

3.3.2

Partycjonowanie mieszaj¡ce (orem2)

. . . . . . . . . . . . . .

37

3.3.3

Partycjonowanie na kolumnie wirtualnej (orem2) . . . . . . . .

41

3.3.4

Partycjonowanie interwaªowe (orem2) . . . . . . . . . . . . . .

43

3.3.5

Partycjonowanie dwupoziomowe interwaªowo-listowe (orem2) .

47

3.3.6

Partycjonowanie dwupoziomowe zakresowo-mieszaj¡ce (orem2)

50

Generacja danych testowych . . . . . . . . . . . . . . . . . . . . . . .

53

3.4.1

Generacja danych tabeli klienci

. . . . . . . . . . . . . . . . .

54

3.4.2

Generacja danych tabeli zamownienia . . . . . . . . . . . . . .

56

Aplikacja testowa . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

57

3.5.1

Budowa i dziaªanie aplikacji

. . . . . . . . . . . . . . . . . . .

57

3.5.2

Zapytania testowe . . . . . . . . . . . . . . . . . . . . . . . . .

58

4 Testy

61

4.1

Tabele klienci, klienci_ref oraz klienci_hash . . . . . . . . . . . . . .

62

4.2

Tabela zamowienia

64

4.3

Tabela zamowienia_ref

. . . . . . . . . . . . . . . . . . . . . . . . .

68

4.4

Tabela zamowienia_hash . . . . . . . . . . . . . . . . . . . . . . . . .

71

4.5

Tabela zamowienia_list

. . . . . . . . . . . . . . . . . . . . . . . . .

75

4.6

Tabela zamowienia_inter

. . . . . . . . . . . . . . . . . . . . . . . .

79

4.7

Tabela zam_inter_list

. . . . . . . . . . . . . . . . . . . . . . . . . .

83

4.8

Tabela zam_range_hash . . . . . . . . . . . . . . . . . . . . . . . . .

87

4.9

Wnioski z bada« testowych . . . . . . . . . . . . . . . . . . . . . . . .

91

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

5 Podsumowanie

93

A Zaª¡cznik A - kod ¹ródªowy aplikacji testowej

95

2

Spis rysunków 1

Równolegªe wykonanie zª¡cze« na partycjach. Opracowano na podstawie rysunku Figure 3-1 Parallel Execution of a Full Partition-wise

Join [10] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

Partycjonowanie zakresowe. Opracowano na podstawie rysunku Fi-

gure 2-2 List, Range, and Hash Partitioning [2] 3

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . .

. . . . . . . . . . . . . . . .

24

Globalny indeks partycjonowany tabeli partycjonowanej. Opracowano na podstawie rysunku Figure 2-7 Global Partitioned Index [2]

9

20

Indeks partycjonowany lokalnie. Opracowano na podstawie rysunku

Figure 2-6 Local Partitioned Index [2] . . . . . . . . . . . . . . . . . . 8

17

Partycjonowanie referencyjne. Opracowano na podstawie rysunku Fi-

gure 2-5 With Reference Partitioning [2] 7

15

Partycjonowanie dwupoziomowe zakresowo-mieszaj¡ce. Opracowano na podstawie rysunku Figure 2-3 Composite Partitioning [2]

6

14

Partycjonowanie listowe. Opracowano na podstawie rysunku Figure

2-2 List, Range, and Hash Partitioning [2] . . . . . . . . . . . . . . . 5

13

Partycjonowanie mieszaj¡ce. Opracowano na podstawie rysunku Fi-

gure 2-2 List, Range, and Hash Partitioning [2] 4

11

. . . .

26

Zwi¡zek mi¦dzy niepartycjonowanym indeksem globalnym i tabel¡ partycjonowan¡. Opracowano na podstawie rysunku Figure 2-8 Global

Nonpartitioned Index [2] 10

. . . . . . . . . . . . . . . . . . . . . . . . .

27

Lista gªównych parametrów konguracyjnych wygenerowana przez narz¦dzie DBCA przy okazji tworzenia bazy danych dbtest na maszynie orem1.

11

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31

Plan wykonania zapytania dla tabeli klienci_ref o 30 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu przycinania partycji.

13

30

Diagram relacyjny przedstawiaj¡cy bazowy model danych. Opracowanie wªasne.

12

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . .

63

Plan wykonania zapytania dla tabeli klienci_hash o 30 mln wierszy, obrazuj¡cy przeprowadzenie zapytania równolegªego.

3

. . . . . . . . .

63

14

Plan wykonania zapytania nr 6 dla tabeli zamowienia o 60 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu zrównoleglenia i wykorzystania indeksu globalnie partycjonowanego na kluczu obcym. . . . . . . .

15

67

Plan wykonania zapytania nr 3 dla tabeli zamowienia o 30 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu przycinania partycji. Przeszukiwana byªa tylko pierwsza partycja indeksu globalnie partycjonowanego na kluczu obcym id_klienta.

16

. . . . . . . . . . . . . . . . . .

67

Plan wykonania zapytania nr 6 dla tabeli zamowienia_ref o 60 mln wierszy, wskazuj¡cy na równolegle wykonywane zª¡cze« na poziomie partycji oraz dynamiczne przycinanie partycji. . . . . . . . . . . . . .

17

71

Plan wykonania zapytania nr 6 dla tabeli zamowienia_hash o 60 mln wierszy, wskazuj¡cy na równolegle wykonywane zª¡cze« na poziomie partycji.

18

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

75

Plan wykonania zapytania nr 4 dla tabeli zamowienia_list o 60 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu zrównoleglenia i przycinania partycji. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19

79

Plan wykonania zapytania nr 2 dla tabeli zamowienia_inter o 60 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu zrównoleglenia i przycinania partycji. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

20

83

Plan wykonania zapytania nr 5 dla tabeli zam_range_hash o 60 mln wierszy, wykorzystanie dwóch mechanizmów poprawiaj¡cych wydajno±¢ - przycinania partycji oraz zª¡cze« na poziomie partycji. . . . . .

4

90

1

Wst¦p W dzisiejszych czasach coraz wi¦cej rm stoi przed wyzwaniem obsªugi tzw.

Bardzo Du»ych Baz Danych (ang. Very Large Databases - VLDB). Nie ma jednoznacznej odpowiedzi na pytanie, jak¡ baz¦ danych mo»emy uzna¢ za bardzo du»¡. Kryteria VLDB do±¢ szybko zmieniaj¡ si¦ w czasie. Wiadomo jednak, »e w miar¦ przyrostu danych, wydajno±¢ bazy danych maleje. Dost¦p do danych staje si¦ wolniejszy, zapytania s¡ wykonywane znacznie dªu»ej ni» w pocz¡tkowej fazie eksploatacji systemu. Równie» administracja okazuje si¦ znacznie bardziej wymagaj¡ca, a mo»e nawet kosztowna. Problematyczne staje si¦ archiwizowanie nieu»ywanych danych. Równocze±nie operacje zwi¡zane z wykonywaniem kopii zapasowej czy odtwarzaniem zajmuj¡ coraz wi¦cej czasu. Wspóªcze±nie »adne powa»ne przedsi¦biorstwo nie mo»e pozwoli¢ sobie na odczuwalny przestój w dost¦pno±ci przechowywanych w bazie danych. Obecnie jeste±my równie» ±wiadkami szybkich zmian w wymaganiach dotycz¡cych analizy ogromnych zbiorów danych. Oprócz tradycyjnej postawy zorientowanej na gromadzenie informacji niezb¦dnych do poprawnego funkcjonowania instytucji, coraz wi¦ksz¡ rol¦ odgrywaj¡ równie» analizy zebranych danych. Wspóªcze±nie dzi¦ki szybkiej analizie bazuj¡cej na historycznej i aktualnej informacji o stanie rmy, kadra zarz¡dzaj¡ca mo»e podejmowa¢ trafniejsze decyzje o strategicznym znaczeniu dla rozwoju danego przedsi¦biorstwa. W odpowiedzi na takie zapotrzebowanie, powstaªa nowa gaª¡¹ technologii baz danych - hurtownie danych (ang. Data Warehouse). Na tego typu bazach pracuj¡ najcz¦±ciej aplikacje typu OLAP (ang. On-line Analytical Processing). Charakteryzuj¡ si¦ one stosunkowo nielicznymi, ale zlo»onymi transakcjami odczytu. Kluczowe znaczenie ma minimalizacja czasu odpowiedzi. Rozwój technologiczny stan¡ª na przeciw równie» tym wymaganiom. Na rynku istnieje wiele rozwi¡za«, w ró»nym stopniu poprawiaj¡cych szeroko rozumian¡ wydajno±¢, zarz¡dzalno±¢ i dost¦pno±¢ du»ych baz danych. W tej pracy skupi¦ si¦ na opcji partycjonowania tabel i indeksów oferowanej przez rm¦ Oracle. Mimo swojej prostoty, jest to pot¦»ny mechanizm, który zyskaª popularno±¢ w wielu przedsi¦biorstwach borykaj¡cych si¦ z wymienionymi wy»ej problemami.

5

1.1 Wprowadzenie do tematu pracy Firma Oracle po raz pierwszy zaprezentowaªa partycjonowanie tabel i indeksów w 1997 roku (Oracle8.0). Partycjonawanie jest dost¦pne dla bazy Oracle Database Enterprise Edition po wykupieniu dodatkowej licencji. Opcja ta uwa»ana jest za jedn¡ z najwa»niejszych i odnosz¡cych najwi¦kszy sukces funkcjonalno±ci bazy danych Oracle, poprawia wydajno±¢ setek tysi¦cy aplikacji bazodanowych [1]. Idea partycjonowania polega na podziale na mniejsze niezale»ne od siebie zycznie cz¦±ci du»ych struktur przechowywanych w bazie danych (tabel, indeksów, tabel zorganizowanych indeksowo) przy u»yciu klucza partycjonowania. Klucz partycjonowania mo»e skªada¢ si¦ z jednej lub wielu kolumn o uporz¡dkowanej kolejno±ci. Deniowane s¡ reguªy na podstawie których serwer bazy danych decyduje, do której z partycji wstawi¢ nowy lub modykowany rekord. Ka»da partycja mo»e mie¢ wªasn¡ nazw¦ i zyczn¡ charakterystyk¦ (np. inna przestrze« tabel oraz ró»ne warto±ci atrybutów skªadowania pctfree, pctused). Partycje mog¡ by¢ równie» opcjonalnie dzielone na podpartycje. Wymagane jest, aby partycja tabeli miaªa te same atrybuty logiczne (kolumny, klucze, wi¦zy integralno±ci) co caªa tabela oraz ka»da partycja indeksu musi indeksowa¢ te same kolumny co caªy indeks. Partycjonowanie poleca si¦ rozwa»y¢, gdy tabela staje si¦ wi¦ksza ni» kilka GB albo tabela przechowuje dane historyczne, które nale»y archiwizowa¢ [2]. Partycjonowanie jest na ogóª kojarzone ze ±rodowiskami hurtowni danych, czyli bazami analitycznymi, zazwyczaj znacznie wi¦kszymi ni» operacyjne. Te ±rodowiska s¡ wyj¡tkowo nara»one na problem wynikaj¡cy z obsªug¡ du»ych ilo±ci danych. Dane hurtowni równie» w naturalny sposób podlegaj¡ podziaªowi wzgl¦dem czasu czy lokalizacji geogracznej, co stanowi typowe kryterium tworzenia partycji. W hurtowni nietrudno o du»¡ tabel¦, która obejmuje zakresem kilka/kilkana±cie lat dziaªalno±ci rmy. Je»eli taka tabela jest partycjonowana z podziaªem na lata b¡d¹ miesi¡ce, mo»na najstarsze z nich (najrzadziej u»ywane) ulokowa¢ w wolniejszych i ta«szych regionach pami¦ci, przez co dysponowa¢ zasobami w sposób bardziej ekonomiczny. Partycjonowanie niekiedy mo»na równie» z powodzeniem zastosowa¢ w klasycznych sysytemach informatycznych typu OLTP (ang. On-line Transaction Processing), charakteryzuj¡cych si¦ obci¡»eniem du»¡ liczb¡ prostych transakcji zapisu i odczytu.

6

1.2 Cel i motywacja pracy Celem pracy jest analiza mo»liwo±ci opcji partycjonowania tabel i indeksów w Oracle Database ze szczególnym uwzgl¦dnieniem nowych cech partycjonowania w wersjach 11g i 11gR2 oraz okre±lenie jej potencjalnego zastosowania. Cz¦±¢ teoretyczna pracy zawiera szeroki opis technik partycjonowania oferowanych przez Oracle oraz przedstawia korzy±ci wynikaj¡ce z ich u»ycia. Nast¦pne rozdziaªy zawieraj¡ opis stworzonego ±rodowisko badawcze oraz wyniki wyniki przeprowadzonych testów. Motywacj¡ do napisania pracy byªa ch¦¢ dokªadniejszego zapoznania si¦ z funkcjonalno±ciami bazy danych Oracle oraz poszerzenia wiedzy na temat oferowanych przez t¦ rm¦ rozwi¡za« technologicznych. Temat pracy - partycjonowanie tabel i indeksów - dotyczy uznanej i dopracowanej opcji Oracle Database, która stanowi dobry przykªad solidno±ci rmy. Kolejne wersje systemu Oracle Database s¡ wzbogacane o nowe mo»liwo±ci partycjonowania. W momencie wyboru tematu pracy aktualn¡ wersj¡ Oracle Database byªa 11gR2. Teraz dost¦pna jest ju» nowa wersja systemu - Oracle Database 12c. Informacje o opcji partycjonowania w 12c mo»na znale¹¢ w Magazynie Oracle z maja/czerwca 2014 roku [6]. Oracle jest uwa»any za jedno z najwa»niejszych ±wiatowych przedsi¦biorstw informatycznych. Z ich rozwi¡za« korzystaj¡ rmy o ró»nym prolu bran»owym, z 145 pa«stw [3]. Ze wszystkich systemów zarz¡dzania baz¡ danych dost¦pnych na rynku, oprogramowanie oferowane przez Oracle jest najcz¦±ciej wybierane. Dochód rmy w 2013 roku wyniósª ponad 10 miliardów USD[4], a na badania i rozwój przeznaczane jest rocznie ponad 5 mld USD [5]. Oracle wypracowaª sobie stabiln¡ i presti»ow¡ pozycj¦ na rynku informatycznym dzi¦ki dynamicznemu rozwojowi, naciskowi na wydajno±¢ i niezawodno±¢ tworzonych technologii oraz umo»liwieniu klientom licencjonowania wygodnej usªugi asysty technicznej, 24/7 wsparcia do wykupionego oprogramowania.

1.3 Ukªad i zakres pracy Rozdziaª 1: Wst¦p Rozdziaª zawiera wprowadzenie teoretyczne oraz ogólny opis opcji partycjonowania tabel i indeksów w Oracle. Zawarte zostaªy równie» informacje dotycz¡ce zakresu tematyki pracy oraz przedstawiono motywacje autorki do jej napisania.

7

Rozdziaª 2: Opcja partycjonowania w Oracle Database W tym rozdziale autorka przedstawiªa potencjalne korzy±ci wynikaj¡ce z u»ycia partycjonowania, wymieniªa i opisaªa poszczególne metody z podziaªem na tradycyjne (do wersji Oracle 10g) i nowsze, wprowadzone od Oracle Database 11g. Opis ka»dej z metod zawiera równie» informacje o ich typowym, zalecanym przez Oracle wykorzystaniu. W rozdziale zaprezentowano równie» perspektywy przydatne do monitorowania partycji.

Rozdziaª 3: ‘rodowisko testów Rozdziaª ma na celu przedstawienie ±rodowiska testowego, na którym przeprowadzone zostaªy badania opcji partycjonowania tabel i indeksów. W dalszej cz¦±ci autorka zamie±ciªa opis modelu relacyjnego, który zostaª potraktowany jako bazowy do przeprowadzania bada« oraz metod¦ generacji danych testowych. W rozdziale zostaªa zaprezentowana równie» aplikacja, która zostaªa stworzona w celu pomocy w przeprowadzeniu testów opcji partycjonowania.

Rozdziaª 4: Testy opcji partycjonowania w Oracle Database 11gR2 W tym rozdziale znajduje si¦ opis oraz wyniki testów w ramach bada« efektywno±ci partycjonowania tabel i indeksów w Oracle Database 11gR2. Przypadki testowe uwzgl¦dniaj¡ ró»ne metody partycjonowania i zostaªy wykonane na dwóch rozmiarach danych.

8

2

Opcja partycjonowania w Oracle Database

2.1 Korzy±ci Partycjonowanie tabel oraz indeksów mo»e przynie±¢ wiele ró»nego rodzaju potencjalnych korzy±ci. Ten rozdziaª zawiera ich opis.

2.1.1

Efektywne administrowanie

Podziaª du»ego obiektu bazodanowego na wiele mniejszych daje administratorowi elastyczno±¢ i kontrol¦ nad partycjonowanymi obiektami. Poniewa» dane tabeli partycjonowanej s¡ przechowywane w cz¦±ciach, ªadowanie oraz usuwanie danych w partycjach jest szybsze i efektywniejsze ni» w przypadku du»ej tabeli. Cz¦sto dodanie nowej partycji jest bardziej opªacalne ni» modykowanie caªej tabeli. Równie» operacje wykonywania kopii zapasowej i odtwarzania przeprowadza si¦ sprawniej. Mo»na skorzysta¢ z wi¦kszej liczby opcji tworzenia kopii zapasowej i odtwarzania partycji, ni» mamy do dyspozycji w przypadku jednej wielkiej tabeli. Partycjonowanie w naturalny sposób mo»e równie» odgrywa¢ znacz¡c¡ rol¦ w procesie ILM (ang. Information Lifecycle Management), poniewa» ka»da z partycja mo»e by¢ zarz¡dzana indywidualnie i przechowywana na ró»nych typach urz¡dze«. Cz¦±¢ danych (partycji), które wymagaj¡ archiwizacji, mo»na przenie±¢ na wolniejsze, ta«sze no±niki. Inne, regularnie u»ytkowane mo»na ulokowa¢ na no±nikach kosztowniejszych, ale zapewniaj¡cych lepsz¡ jakos¢ i szybko±¢ dost¦pu. Dodatkowo, poniewa» z zasady partycje mog¡ ró»ni¢ si¦ parametrami zycznymi, mo»na równie» dokona¢ kompresji wybranych partycji tabeli [7]. Taka taktyka pozwala na ekonomiczne i wydajne zarz¡dzanie zasobami. Kolejn¡ przydatn¡ cech¡ partycjonowania jest mo»liwo±¢ gromadzenia statystyk zarówno na poziomie pojedynczej partycji, jak i caªej tabeli (ang. Incremental Global Statistics). Gdy fragment tabeli partycjonowanej ulega modykacji, statystyki s¡ od±wie»ane w sposób przyrostowy  analizowane s¡ tylko te partycje, w których nast¡piªy modykacje. Opcja ta wymaga ustawienia parametrów DBMS_STATS tabeli partycjonowanej: GRANULARITY na AUTO i INCREMENTAL na TRUE [8]. Dzi¦ki takim ustawieniom mo»na zredukowa¢ czas zbierania statystyk, co jest szczególnie zauwa»alne przy du»ej liczbie partycji [9].

9

2.1.2

Bezpiecze«stwo, dost¦pno±¢

Fizyczny podziaª danych powoduje niezale»no±¢ partycji, a co za tym idzie, równie» zwi¦ksza poziom bezpiecze«stwa i dost¦pno±ci bazy. Administrator bazy danych mo»e okre±li¢, »e ka»da z partycji ma by¢ przechowywana w innej przestrzeni tabel, które mog¦ znajdowa¢ si¦ na ró»nych no±nikach danych. Strategia ta umo»liwia tworzenie kopii zapasowych i odzyskiwania ka»dej z partycji niezale»nie od innych cz¦±ci tabeli. W przypadku awarii bazy, mo»liwe staje si¦ odzyskanie tylko jej aktualnej, aktywnej cz¦±ci, a reszt¡ w tym momencie nie u»ytkowanych danych, zebranych w innych partycjach mo»na zaj¡¢ si¦ w dogodnym momencie. W ten sposób minimalizuje si¦ czas niedost¦pno±ci bazy danych. W razie awarii sprz¦tu, np. dysku uniemo»liwiony jest dost¦p tylko do partycji na tym dysku, natomiast partycje znajduj¡ce si¦ na nieuszkodzonych dyskach pozostaj¡ nadal aktywne.

2.1.3

Przycinanie partycji (ang. partitioning pruning)

Pomimo i» partycjonowanie jest postrzegane przede wszystkim jako element decyduj¡cy o dost¦pno±ci i ªatwo±ci zarz¡dzania baz¡ danych, to ma ono równie» niebagatelny wpªyw na wydajno±¢ u»ytkowania bazy. Jednym z najprzydatniejszych efektów zwi¡zanych z partycjonowaniem jest przycinanie partycji (ang. partitioning pruning). Jest to prosty mechanizm mog¡cy poprawi¢ szybko±¢ wykonywania zapytania. Przycinanie partycji jest ±ci±le zwi¡zane z dziaªaniem optymalizatora zapyta«, którego zadaniem jest analiza klauzul FROM oraz WHERE instrukcji SQL, pod k¡tem wyeliminowania z procesu wyszukiwania tych partycji, które na pewno nie zawieraj¡ »¡danych danych. W przypadku gdy optymalizator wykryje zapytanie si¦gaj¡ce do partycjonowanej tabeli i warunki selekcji w zapytaniu odpowiadaj¡ reguªom zdeniowanym dla pewnej grupy partycji, to wygeneruje plan wykonania zapytania pomijaj¡cy te partycje, dla których ten warunek nie jest speªniony. Warto zaznaczy¢, i» mechanizm przycinania partycji mo»e by¢ ª¡czony z dost¦pem do indeksu. Gdy indeks jest podzielony wedªug innych kolumn ni» odpowiadaj¡ca mu tabela, wówczas niepotrzebne partycje indeksu zostan¡ odrzucone, nawet je±li partycje odpowiadaj¡cej mu tabeli pozostan¡. Technika ta mocno redukuje ilo±¢ danych pobieranych z dysku, a tak»e skraca czas przetwarzania zapytania SQL, co ma bezpo±redni wpªyw na zwi¦kszenie wydajno±ci. Przycinanie partycji sprawdza

10

si¦ szczególnie np. w ±rodowiskach hurtowni danych, gdzie wyszukiwanie informacji nale»y do najpowszechniejszych dziaªa«. Mechanizm ten wspóªpracuje z wszystkimi innymi technikami Oracle poprawiaj¡cymi wydajno±¢.

2.1.4

Zª¡czenia partycji (ang. partition-wise joins)

W wyniku stosowania partycjonowania mo»na udoskonali¢ wydajno±¢ zª¡czania wielu tabel, stosuj¡c w tym celu technik¦ partycjonowania na poziomie zª¡cze« (ang. partition-wise joins). Technika ta mo»e by¢ stosowa¢, gdy przynajmniej jedna z ª¡czonych tabel jest partycjonowana wedªug klucza zª¡czenia. Najbardziej jednak korzystne s¡ tzw. full partition-wise joins, kiedy obie tabele s¡ partycjonowane wedªug kolumny, na której wykonywane jest zª¡czenie. Partycjonowanie na poziomie zª¡cze« powoduje podziaª du»ych zª¡cze« na mniejsze obejmuj¡ce kolejne pary odnosz¡cych sie do siebie partycji. Dzi¦ki temu caªkowite zª¡czenie mo»e by¢ wykonane w krótszym czasie. Proces ª¡czenia par partycji mo»na dodatkowo zrównolegli¢. Poszczególne zª¡czenia mog¡ by¢ wykonywane przez równolegle pracuj¡ce procesy lub serwery. Umo»liwia to optymalne wykorzystanie mocy obliczeniowej.

Rysunek 1: Równolegªe wykonanie zª¡cze« na partycjach. Opracowano na podstawie rysunku Figure 3-1 Parallel Execution of a Full Partition-wise Join [10]

2.1.5

Zrównoleglenie, skalowalno±¢

Równie» polecenia DML mog¡ by¢ wykonywane równolegle dla wielu partycji. Mechanizm ten w istotny sposób wpªywa na logik¦ transakcji, blokad i zu»ycia pami¦ci, dlatego musi by¢ jawnie wª¡czony poleceniem ALTER SESSION ENABLE

11

PARALLEL DML [11]. Pomaga to zredukowa¢ czas odpowiedzi na zapytania intensywnie korzystaj¡ce z bazy danych. Warto zauwa»y¢, »e dobrze zaprojektowane u»ycie opcji partycjonowania mo»e doprowadzi¢ do tego, »e wydajno±¢ wielu zapyta« zostanie niemal uniezale»niona od przyrostu danych.

2.2 Metody partycjonowania do wersji Oracle 10g 2.2.1

Partycjonowanie Zakresowe (ang. Range Partitioning)

Przy tej metodzie rozdziaª rekordów pomi¦dzy partycje odbywa si¦ wedªug przynale»no±ci warto±ci kolumny-klucza do predeniowanych przedziaªów. Oznacza to, »e do danej partycji traaj¡ rekordy ze ±ci±le okre±lonego dla niej zakresu, np. dat albo liczb. Dla ka»dej z partycji podaje si¦ najwi¦ksz¡ warto±¢ klucza partycjonowania jak¡ mo»e przyj¡¢ rekord do niej nale»¡cy (podajemy wyª¡cznie maksymaln¡ warto±¢ zakresu). Warto±¢ minimalna jest niejawnie okre±lona przez Oracle na podstawie denicji poprzednich partycji. Je±li warto±¢ atrybutu partycjonuj¡cego dla wstawianego rekordu nie pasuje do »adnego z okre±lonych zakresów, wówczas system zgªasza bª¡d. Nie jest jednak konieczne okre±lanie maksymalnego zakresu dla ostatniej partycji. Sªowo kluczowe maxvalue wskazuje systemowi Oracle, aby korzystaª z tej partycji w odniesieniu do wszystkich danych, które nie mog¡ by¢ zapisane we wcze±niejszych partycjach. Kolejne warto±ci klucza partycjonowania s¡ zwykle zapisywane w tej samej partycji.

Listing 1: Przykªad tworzenia tabeli partycjonowanej zakresowo.

CREATE TABLE zamowienie ( zamowienie_id koszt_zamowienia data_zamowienia

NUMBER (5) ,

NUMBER (10) , DATE )

PARTITION BY RANGE ( data_zamowienia )( PARTITION zam_sty2013 VALUES LESS THAN ( TO_DATE ( '02/01/2013 ' , ' MM / DD / YYYY ')) , PARTITION zam_lut2013 VALUES LESS THAN ( TO_DATE ( '03/01/2013 ' , ' MM / DD / YYYY ')) , PARTITION zam_mar2013 VALUES LESS THAN ( TO_DATE ( '04/01/2013 ' , ' MM / DD / YYYY ')) , PARTITION zam_inne VALUES LESS THAN MAXVALUE );

12

Rysunek 2: Partycjonowanie zakresowe. Opracowano na podstawie rysunku Figure

2-2 List, Range, and Hash Partitioning [2]

2.2.2

Partycjonowanie Mieszaj¡ce (ang. Hash Partitioning)

W tej metodzie przynale»no±¢ do partycji jest determinowana przez funkcj¦ mieszaj¡c¡ dziaªaj¡c¡ na kluczu partycji, któr¡ tworzy Oracle bez udziaªu u»ytkownika. Im bardziej ró»norodne warto±ci klucza partycjonowania, tym lepsza dystrybucja wierszy w partycjach. Partycjonowanie mieszaj¡ce cz¦sto rozmieszcza zbiory rekordów w wi¦kszej liczbie partycji ni» metoda zakresowa, potencjalnie zmniejszaj¡c prawdopodobie«stwo opó¹nie« wej±cia-wyj±cia. Ze wzgl¦du na sposób implementowania odwzorowania partycji w Oracle, zalecane jest aby liczba partycji w tabeli byªa pot¦g¡ 2, co pomaga uzyska¢ równ¡ dystrybucj¦ danych. Podobnie jak w przypadku partycjonowania zakresowego mo»na okre±li¢ nazw¦ (mo»e tez by¢ generowana automatycznie przez system) ka»dej z partycji oraz wykorzystywan¡ przez ni¡ przestrze« tabel. Je±li liczba partycji przekracza liczb¦ przestrzeni tabel, to partycje s¡ umieszczane w kolejnych przestrzeniach tabel za pomoc¡ algorytmu karuzelowego (ang. round-robin). Ten typ partycjonowania jest najcz¦±ciej u»ywany, kiedy zale»y nam na równomiernym rozkªadzie wierszy mi¦dzy partycje, ale nie jeste±my w stanie sami tego zagwarantowa¢.

13

Listing 2: Przykªad tworzenia tabeli partycjonowanej metod¡ mieszaj¡c¡.

CREATE TABLE zamowienie ( zamowienie_id

NUMBER (5) ,

koszt_zamowienia data_zamowienia

NUMBER (10) , DATE

) PARTITION BY HASH ( zamowienie_id ) PARTITIONS 4 STORE IN ( z1 , z2 , z3 , z4 );

Rysunek 3: Partycjonowanie mieszaj¡ce. Opracowano na podstawie rysunku Figure

2-2 List, Range, and Hash Partitioning [2]

2.2.3

Partycjonowanie Listowe (ang. List Partitioning)

Przy partycjonowaniu listowym dla ka»dej z partycji wskazuje si¦ wszystkie mo»liwe warto±ci atrybutu partycjonuj¡cego wstawianych do niej wierszy. Je±li klucz partycjonowania rekordu (dla tej metody jest to zawsze jedna kolumna) nie pasuje do warto±ci »adnej z partycji, wówczas system zgªasza bª¡d. Denicj¦ tabeli partycjonowanej mo»na jednak rozszerzy¢ o partycj¦ umo»liwiaj¡c¡ przechowywanie wszystkich innych warto±ci. Przy deniowaniu takiej partycji wykorzystuje si¦ sªowo kluczowe default. Partycjonowanie zakresowe jest zazwyczaj nieprzydatne w przypadku pojedynczych warto±ci, które nie tworz¡ naturalnego i ci¡gªego zakresu (np. nazwy miast, kody pocztowe). Z kolei partycjonowanie mieszaj¡ce nie sprawdza si¦, gdy trzeba in-

14

dywidualne warto±ci przypisa¢ do konkretnej partycji, poniewa» ta metoda, z natury dziaªania, mo»e mapowa¢ kilka powi¡zanych ze sob¡ warto±ci na ró»ne partycje. W takich przypadkach warto zastosowa¢ partycjonowanie listowe.

Listing 3: Przykªad tworzenia tabeli partycjonowanej listowo.

CREATE TABLE zamowienie ( zamowienie_id koszt_zamowienia data_zamowienia

NUMBER (5) , NUMBER (10) , DATE ,

miejsce_zam VARCHAR2 (30) ) PARTITION BY LIST ( miejsce_zam )( PARTITION mazowieckie VALUES ( ' Warszawa ' , ' Radom ' , ' Plock ') , PARTITION slaskie VALUES ( ' Czestochowa ' , ' Katowice ' , ' Cieszyn ') , PARTITION malopolskie VALUES ( ' Zakopane ' , ' Tarnow ' , Krakow ) , PARTITION inne VALUES ( DEFAULT ) );

Rysunek 4: Partycjonowanie listowe. Opracowano na podstawie rysunku Figure 2-2

List, Range, and Hash Partitioning [2]

2.2.4

Partycjonowanie Dwupoziomowe (ang. Composite Partitioning)

Partycje uzyskane za pomoc¡ partycjonowania zakresowego mog¡ podlega¢ dalszemu podziaªowi za pomoc¡ partycjonowania mieszaj¡cego albo listowego. W przypadku du»ych tabel jest to opªacalny sposób dzi¦ki, któremu mo»na poª¡czy¢ zalety

15

ró»nych technik partycjonowania w zale»no±ci od potrzeb. Na przykªad partycjonowanie zakresowo-mieszaj¡ce zapewnia lepszy poziom zarz¡dzania wynikaj¡cy z podziaªu zakresowego i wydajne rozmieszczenie danych wynikaj¡ce z metody mieszaj¡cej. Partycjonowanie dwupoziomowe w odniesieniu do niektórych zapyta« pozwala na zwi¦kszenie korzy±ci wynikaj¡cych z przycinania partycji. S¡ to zapytania, które w klauzuli WHERE zawieraj¡ warunki selekcji opieraj¡ce si¦ na kolumnach kluczy partycji oraz subpartycji. U»ycie kolumny, na której cz¦sto wykonywane s¡ zª¡czenia, jako klucza subpartycji wspiera mechanizm zª¡cze« na poziomie partycji. Dochodzi wtedy do zª¡cze« jedynie na poziomie subpartycji. Partycjonowanie dwupoziomowe nie jest dost¦pne dla tabel o organizacji indeksowej IOT.

Listing 4: Przykªad tworzenia tabeli partycjonowanej metod¡ zakresowo-mieszaj¡c¡.

CREATE TABLE zamowienie ( zamowienie_id koszt_zamowienia data_zamowienia

NUMBER (5) , NUMBER (10) , DATE

) PARTITION BY RANGE ( data_zamowienia ) SUBPARTITION BY HASH ( zamowienie_id ) SUBPARTITION TEMPLATE ( SUBPARTITION zam1 TABLESPACE ts1 , SUBPARTITION zam2 TABLESPACE ts2 , SUBPARTITION zam3 TABLESPACE ts3 ,) ( PARTITION zam_sty2013 VALUES LESS THAN ( TO_DATE ( '02/01/2013 ' , ' MM / DD / YYYY ')) , PARTITION zam_lut2013 VALUES LESS THAN ( TO_DATE ( '03/01/2013 ' , ' MM / DD / YYYY ')) , PARTITION zam_mar2013 VALUES LESS THAN ( TO_DATE ( '04/01/2013 ' , ' MM / DD / YYYY ')) , );

16

Rysunek 5: Partycjonowanie dwupoziomowe zakresowo-mieszaj¡ce. Opracowano na podstawie rysunku Figure 2-3 Composite Partitioning [2]

2.3 Nowe w 11g metody i wªa±ciwo±ci partycjonowania 2.3.1

Partycjonowanie Interwaªowe (ang. Interval Partitioning)

Partycjonowanie interwaªowe poszerza mo»liwo±ci metody zakresowej. Eliminuje problem jawnego deniowania partycji zakresowych przez administratora. W przypadku monotonicznego wzrostu warto±ci klucza partycjonowania, kolejne partycje nie musz¡ by¢ na bie»¡co dodawane przez administratora bazy danych. System Oracle na podstawie zadanego interwaªu okre±la, do której partycji nale»y wstawi¢ nowy wiersz. Mo»na np. okre±li¢ zasad¦ tworzenia nowej partycji co miesi¡c. Pierwsz¡ partycj¦ nale»y utworzy¢ samodzielnie. Gdy warto±¢ klucza partycjonowania w nowych rekordach przekracza zakres istniej¡cych partycji, automatycznie tworzona jest nowa partycja zakresowa o zadanej szeroko±ci. Nazwa nowej partycji nadawana jest automatycznie. Istniej¡ jednak pewne dodatkowe ograniczenia dotycz¡ce tworzenia partycji interwaªowych. Klucz partycjonowania musi by¢ typu DATE lub NUMBER. Nie mo»liwe jest równie» zastosowanie tej techniki w stosunku do tabel o organizacji indeksowej - IOT. Szczególnie nale»y uwa»a¢ na tworzenie niechcianych partycji, które mog¡ powsta¢ w wyniku pomyªkowego wprowadzenia danych rekordu, np. bª¦dnej daty. W tym przypadku warto kontrolowa¢ warto±ci klucza partycjonowania przed wstawieniem nowego wiersza.

17

Listing 5: Przykªad tworzenia tabeli partycjonowanej interwaªowo.

CREATE TABLE zamowienie ( zamowienie_id

NUMBER (5) not null ,

koszt_zamowienia

NUMBER (10) not null ,

data_zamowienia

DATE not null

) PARTITION BY RANGE ( data_zamowienia ) INTERVAL ( numtoyminterval (1 , ' MONTH ')) ( PARTITION P1 VALUES LESS THAN ( TO_DATE ( '1 -1 -2013 ' , ' MM / DD / YYYY ')) , PARTITION P2 VALUES LESS THAN ( TO_DATE ( '1 -2 -2013 ' , ' MM / DD / YYYY ')) , PARTITION P3 VALUES LESS THAN ( TO_DATE ( '1 -3 -2013 ' , ' MM / DD / YYYY ')) );

2.3.2

Partycjonowanie Systemowe (ang. System Partitioning)

Partycjonowanie systemowe umo»liwia tworzenie partycji bez wskazywania klucza partycjonowania. Dla ka»dej z partycji nale»y jedynie wskaza¢ przestrze« tabel w jakiej ma si¦ znajdywa¢. Wszystkie aspekty dotycz¡ce partycji musz¡ by¢ kontrolowane przez aplikacj¦. Oznacza to, »e wymagane jest np. aby przy operacji INSERT wskaza¢ konkretn¡ partycj¦, inaczej operacja si¦ nie powiedzie. Z powodu braku wyszczególnienia kluczy partycjonowania, typowe korzy±ci wydajno±ciowe dost¦pne dla tabel partycjonowanych nie mog¡ by¢ zastosowane przy tej metodzie. Nie dziaªa mechanizm przycinania partycji ani efektywnych zª¡cze« (ang. wise-joins). Zalety wynikaj¡ce z podziaªu zycznego tabeli na mniejsze cz¦±ci jednak ci¡gle s¡ aktualne (dost¦pno±¢, bezpiecze«stwo, zarz¡dzalno±¢).

Listing 6: Przykªad tworzenia tabeli partycjonowanej systemowo.

CREATE TABLE zamowienie ( zamowienie_id

NUMBER (5) not null ,

koszt_zamowienia

NUMBER (10) not null ,

data_zamowienia

DATE not null )

PARTITION BY SYSTEM ( PARTITION P1 TABLESPACE zam1 18

PARTITION P2 TABLESPACE zam2 PARTITION P3 TABLESPACE zam3 PARTITION P3 TABLESPACE zam4 );

2.3.3

Partycjonowanie Referencyjne (ang. Reference Partitioning)

Metoda referencyjna pozwala na tworzenie partycji bazuj¡cych nie na warto±ciach z partycjonowanej tabeli, ale na odwoªaniu do klucza obcego z innej tabeli. Mo»e to by¢ przydatne przy partycjonowaniu tabel w spójny sposób, nawet je»eli nie wspóªdziel¡ one tych samych kolumn. Jest to szczególnie opªacalna metoda w przypadku, kiedy wiadomo, »e tabele b¦d¦ cz¦sto podlegaªy zª¡czeniom. Przy tym partycjonowaniu mamy doczynienia z dwoma tabelami b¦d¡cymi w relacji nadrz¦dna-podrz¦dna, które zostaj¡ logicznie tak samo partycjonowane. Na pocz¡tku nale»y utworzy¢ tabel¦ nadrz¦dn¡  rodzica, a potem tabel¦ podrz¦dn¡  dziecko z odpowiednim ograniczeniem integralno±ci klucza obcego, odwoªuj¡cego si¦ do tabeli  rodzica, doª¡czaj¡c klauzul¦ partycjonowania wskazuj¡c¡ wspomniany klucz obcy. Tabela podrz¦dna dziedziczy sposób partycjonowania od tabeli nadrz¦dnej. W przypadku wcze±niejszego istnienia tabel mo»na skorzysta¢ z polecenia

alter table. Wszystkie podstawowe metody partycjonowania (zakresowe, mieszaj¡ce i listowe) s¡ dost¦pne w poª¡czeniu z partycjonowaniem referencyjnym. W przypadku partycjonowania referencyjnego administrowanie obiektami jest znacznie uªatwione, gdy» operacje utrzymania na partycji tabeli  rodzica przenosz¡ si¦ kaskadowo na partycje tabeli- dziecka. W zwi¡zku z tym nie ma potrzeby wykonywania dodatkowych operacji na tabeli podrz¦dnej. Ponadto warto zauwa»y¢, »e partycjonowanie referencyjne zapobiega zb¦dnej redundancji danych, poniewa» nie ma potrzeby powielania klucza partycjonowania w tabeli podrz¦dnej.

Listing 7: Przykªad tworzenia tabeli partycjonowanej referencyjnie.

CREATE TABLE zamowienie ( zam_id

NUMBER (5) NOT NULL ,

koszt_zamowienia

NUMBER (10 ,2) NOT NULL ,

data_zam

NOT NULL ,

DATE

CONSTRAINT zamowienie_pk PRIMARY KEY ( zamowienie_id )) PARTITION BY RANGE ( data_zam ) ( PARTITION zam_sty2013 VALUES LESS 19

THAN ( TO_DATE ( '02/01/2013 ' , ' MM / DD / YYYY ')) , PARTITION zam_lut2013 VALUES LESS THAN ( TO_DATE ( '03/01/2013 ' , ' MM / DD / YYYY ')) , PARTITION zam_mar2013 VALUES LESS THAN ( TO_DATE ( '04/01/2013 ' , ' MM / DD / YYYY ')) , PARTITION zam_inne VALUES LESS THAN MAXVALUE ); CREATE TABLE pozycja ( pozycja_id nadrzedna_id nazwa

NUMBER NOT NULL , NUMBER NOT NULL , VARCHAR2 (50) NOT NULL ,

opis

VARCHAR2 (200) ,

cena

NUMBER (10 ,2) ,

CONSTRAINT pozycja_zam_pk PRIMARY KEY ( pozycja_id ) , CONSTRAINT zamowienie_pozycja_fk FOREIGN KEY ( nadrzedna_id ) REFERENCES zamowienie ( zam_id )) PARTITION BY REFERENCE ( zamowienie_pozycja_fk );

Rysunek 6: Partycjonowanie referencyjne. Opracowano na podstawie rysunku Figure

2-5 With Reference Partitioning [2]

20

2.3.4

Partycjonowanie na Bazie Kolumny Wirtualnej (ang. Virtual Column Based Partitioning)

Kolumny wirtualne zostaªy wprowadzone jako nowo±¢ Oracle 11g, w zwi¡zku z tym staªo si¦ równie» mo»liwe partycjonowanie na ich podstawie. Tym sposobem kluczem partycjonowania nie musi by¢ zyczna kolumna, ale równie» wyra»enie powstaªe na bazie jednej lub kilku istniej¡cych kolumn, przechowywane jako metadana. Kolumn wirtualnych mo»na u»ywa¢ jako kluczy partycjonowania we wszystkich z podstawowych strategii partycjonowania, jaki i partycjonowaniu interwaªowym oraz referencyjnym. Listing 8: Przykªad tworzenia tabeli partycjonowanej listowo na podstawie kolumny wirtualnej.

CREATE TABLE uzytkownicy ( id

NUMBER ,

nazwa

VARCHAR2 (20) ,

pierwsza_litera

VARCHAR2 (1)

GENERATED ALWAYS AS ( UPPER ( SUBSTR ( TRIM ( nazwa ) , 1 , 1)) ) VIRTUAL ) PARTITION BY LIST ( pierwsza_litera )( PARTITION part_a_g VALUES ( 'A ' , 'B ' , 'C ' , 'D ' , 'E ' , 'F ' , 'G ') , PARTITION part_h_n VALUES ( 'H ' , 'I ' , 'J ' , 'K ' , 'L ' , 'M ' , 'N ') , PARTITION part_o_u VALUES ( 'O ' , 'P ' , 'Q ' , 'R ' , 'S ' , 'T ' , 'U ') , PARTITION part_v_z VALUES ( 'V ' , 'W ' , 'X ' , 'Y ' , 'Z ') );

2.3.5

Partycjonowanie Dwupoziomowe w Oracle 11gR2

W Oracle Database 11gR2 dost¦pne s¡ nast¦puj¡ce kombinacje partycji dwupoziomowych na bazie podstawowych metod partycjonowania: zakresowo-zakresowe, zakresowo-listowe, zakresowo-mieszaj¡ce, listowo-mieszaj¡ce, listowo-listowe, listowomieszajace, mieszaj¡co-mieszaj¡ce. Ponadto z nowymi opcjami partycjonowania mo»na tworzy¢ partycje dwupoziomowe typu: interwaªowo-zakresowe, interwawaªowo-listowe, interwaªowo-mieszaj¡ce.

21

2.4 Partycjonowanie indeksów Partycjonowanie indeksów przynosi korzy±ci tego samego typu co partycjonowanie tabel. Dodatkowo pot¦guje mo»liwo±ci zwi¦kszenia stopnia wspóªbie»no±ci transakcji oraz minimalizuje rywalizacj¦ transakcji, poprzez rozproszenie operacji wej±cia/wyj±cia. Partycjonowanie indeksów jest równie» polecane, gdy zale»y nam na tym, aby przy przeprowadzaniu operacji dotycz¡cych konserwacji i utrzymania danych nie ingerowa¢ w caªy indeks, np. nie przebudowywa¢ caªego indeksu, po usuni¦ciu cz¦±ci danych z tabeli. Mo»liwe jest tworzenie indeksów partycjonowanych dla tabel partycjonowanych, jak i niepartycjonowanych. Tabela partycjonowana mo»e natomiast mie¢ zarówno indeks partycjonowany jaki i niepartycjonowany. Indeksy mog¡ by¢ partycjonowane niezale»nie od tabel (globalne) lub mog¡ te» by¢ uzale»nione od partycji tabel, do których nale»¡ (lokalne). W przypadku partycjonowania dwupoziomowego, indeksy subpartycji s¡ z zasady zawsze partycjonowane lokalnie.

2.4.1

Lokalny Indeks Partycjonowany

Przy partycjonowaniu indeksów lokalnie partycje indeksów s¡ zgodne z partycjami tabeli (zgodno±¢ atrybutów partycjonuj¡cych i zakresów partycji). Ka»da partycja indeksu lokalnego odpowiada tylko jednej partycji indeksowanej tabeli. Indeks tego typu jest w peªni uzale»niony od schematu partycjonowanej tabeli. Indeks bitmapowy mo»e by¢ tylko lokalny wzgl¦dem partycjonowanej tabeli. Indeks partycjonowany lokalnie mo»e by¢ unikatowy, je±li klucz partycjonowania tabeli jest podzbiorem kolumn klucza indeksu. System Oracle automatycznie zarz¡dza indeksami lokalnymi, utrzymuj¡c ich peªn¡ synchronizacj¦ z odpowiadaj¡c¡ partycj¡. Oznacza to, »e w przypadku dodania nowej partycji tabeli, automatycznie jest generowana odpowiadaj¡ca jej partycja indeksu. Usuni¦cie partycji tabeli spowoduje samoczynne usuni¦cie skorelowanej z ni¡ partycji indeksu, bez uniewa»niania »adnej innej partycji indeksu, jak w przypadku indeksu globalnego. Z tego powodu indeksy partycjonowane lokalnie s¡ uwa»ane za najprostsze w zarz¡dzaniu i utrzymaniu. Zaleca si¦ stosowanie lokalnego indeksowania je±li klucz partycjonowania jest podzbiorem klucza indeksu i priorytetem jest wygoda zarz¡dzania i przepustowo±¢

22

systemu. Dlatego indeksy lokalne s¡ polecane dla hurtowni danych czy systemów wspomagania decyzji DSS. Lokalny indeks partycjonowany mo»e byc preksowany lub niepreksowany.

Indeks preksowany. Pierwsze kolumny indeksu bazuj¡ na kluczu partycjonowania tabeli, z zachowaniem ich kolejno±ci. Wykrywanie tego rodzaju indeksu jest mniej kosztowne. U»ycie lokalnego indeksu preksowanego umo»liwia pomini¦cie partycji przy u»yciu mechanizmu przycinania partycji, je±li zapytanie zawiera klucz partycjonowania w klauzuli WHERE.

Indeks niepreksowany. Pierwsze kolumny indeksu nie bazuj¡ na atrybutach partycjonuj¡cych tabeli. Cz¦sto jest u»ywany do indeksowania kolumny, która nie wchodzi w skªad klucza partycjonowania tabeli, a chcemy, aby indeks byª partycjonowany na tym samym kluczu co tabela podstawowa. Nie wspomaga dodatkowo mechanizmu przycinania partycji. Nie jest zalecany w aplikacjach typu OLTP. Jest jednak skuteczny w dost¦pie do danych, które obejmuj¡ wiele partycji, poniewa» operacje te mo»na zrównolegli¢. Oznacza to, »e indeks lokalny niepreksowany warto zastosowa¢ w systemach wspomagania decyzji. Cz¦sto wykonywane w nich zapytania zakresowe bazuj¡ce na kluczu indeksu mog¡ by¢ szybciej przeprowadzane, gdy» partycje indeksu mog¡ by¢ przeszukiwane równolegle. [10].

Listing 9: Przykªad tworzenia indeksu partycjonowanego lokalnie.

CREATE INDEX zamowienie_local ON zamowienie ( zamowienie_id ) LOCAL ;

2.4.2

Indeks Globalny

Indeks globalny mo»e by¢ partycjonowany lub niepartycjonowany. Indeksowanie globalne zalecane jest, gdy indeks jest unikatowy i priorytetem jest minimalizacja czasu odpowiedzi na »¡danie u»ytkownika, dlatego takie indeksowanie mo»e by¢ z korzy±ci¡ stosowane w aplikacjach typu transakcyjnego.

23

Rysunek 7: Indeks partycjonowany lokalnie. Opracowano na podstawie rysunku Fi-

gure 2-6 Local Partitioned Index [2]

Indeks globalny partycjonowany. Indeks partycjonowany globalnie jest jawnie deniowany i podlega partycjonowaniu metod¡ mieszaj¡c¡ lub zakresow¡. Klucz indeksu mo»e ró»ni¢ si¦ od klucza partycjonowania tabeli. Schemat partycjonowania indeksu mo»e by¢ wi¦c niezale»ny od partycji tabeli. Oracle nie wspiera niepreksowanych globalnych indeksów partycjonowanych. Zarz¡dzanie globalnymi partycjonowanymi indeksami jest szczególnie skomplikowane. Przenoszenie, usuwanie rekordów wybranej partycji tabeli wpªywa na wszystkie partycje indeksu. Ogranicza to niezale»no±¢ partycji tabeli. Konsekwentnie próba przywrócenia danej partycji tabeli wymaga ponownego stworzenia wszystkich partycji indeksu globalnego. Indeksów globalnych nale»y wi¦c unika¢ w systamach bazuj¡cych na strategii rolling window, gdy regularnie co okres czasu tworzy si¦ now¡ partycj¦, a najstarsz¡ si¦ archiwizuje i usuwa. Domy±lnie wiele operacji sªu»¡cych zarz¡dzaniu indeksami globalnymi powoduje, »e danej partycji zostaje nadany status UNUSABLE. Mo»na zapobiec takiemu zachowaniu przy pomocy instrukcji UPDATE GLOBAL INDEXES, wtedy partycje indeksów globalnych s¡ aktualizowane. Konsekwencj¡ tej zmiany jest jednak dªu»sze wykonywanie instrukcji DDL. Generowanie globalnego indeksu partycjonowanego

24

zakresowo

uwzgl¦dnia re-

guªy podobne do tych, których u»ywa si¦, tworz¡c tabele partycjonowane zakresowo. Najwy»sza partycja indeksu musi mie¢ granic¦ okre±lon¡ jako maxvalue. To gwarantuje, »e wszystkie wiersze tabeli b¦d¡ miaªy przydzielony indeks. Warto jednak zauwa»y¢, »e nie mo»na w tradycyjny sposób doda¢ nowej partycji o najwy»szym zakresie, poniewa» jest on explicite okre±lony przez parametr maxvalue. W tym wypadku nale»y skorzysta¢ z instrukcji INDEX SPLIT PARTITION. Próba usuni¦cia niepustej partycji indeksu instrukcj¡ ALTER INDEX DROP PARTITION spowoduje, »e nast¦pna wg zakresu partycja zostanie oznaczona jako UNUSABLE. Nie mo»na oczywi±cie usun¡¢ najwy»szej partycji indeksu. Podobnie jak w przypadku globalnych indeksów partycjonowanych zakresowo, instrukcje tworzenia globalnych indeksów partycjonowanych metod¡

mieszaj¡c¡

maj¡ skªadni¦ wspóln¡ z poleceniami generowania tabel partycjonowanych t¡ sam¡ metod¡. Indeksy globalne partycjonowane t¡ technik¡ mog¡ zwi¦kszy¢ wydajno±¢ w sytuacjach, w których w ±rodowisku OLTP niewielka liczba bloków ko«cowych w¦zªów indeksu niepartycjonowanego poddawana jest du»ej rywalizacji. Z tego typu indeksów w znacz¡cym stopniu mog¡ korzysta¢ zapytania, które w klauzuli WHERE maj¡ znak równo±ci lub operator IN. Listing 10: Przykªad tworzenia indeksu globalnego partycjonowanego metod¡ mieszaj¡c¡.

CREATE INDEX zamowienie_global ON zamowienie ( zamowienie_id ) GLOBAL PARTITION BY HASH ( zamowienie_id ) ( PARTITION Z1 tablespace idx_1 PARTITION Z2 tablespace idx_2 PARTITION Z3 tablespace idx_3 PARTITION Z4 tablespace idx_4 );

Indeks globalny niepartycjonowany. Generalnie indeks globalny niepartycjonowany ma wªa±ciwo±ci zwykªego indeksu tabeli niepartycjonowanej. Równie» jego tworzenie przebiega tak samo jak generowanie zwykªego indeksu (skªadnia instrukcji jest identyczna). Tego typu indeksowanie jest szczególnie polecane w przypadku systemów OLTP.

25

Rysunek 8: Globalny indeks partycjonowany tabeli partycjonowanej. Opracowano na podstawie rysunku Figure 2-7 Global Partitioned Index [2]

Rysunek 9: Zwi¡zek mi¦dzy niepartycjonowanym indeksem globalnym i tabel¡ partycjonowan¡. Opracowano na podstawie rysunku Figure 2-8 Global Nonpartitioned

Index [2]

26

2.5 Perspektywy dotycz¡ce partycji tabel i indeksów W przedstawionej poni»ej tabeli zawarte s¡ wszystkie perspektywy sªownika danych dotycz¡ce partycji tabel i indeksów znajduj¡cych si¦ w bazie danych (preks DBA). Informacje te mog¡ by¢ przydatne do monitorowania poszczególnych partycji. Ka»da z wymieninych partycji ma równie» swój ekwiwalent przedstawiaj¡cy dane dast¦pne dla aktywnego u»ytkownika (w nazwie preks ALL) lub dane o obiektach, których wªa±cicielem jest aktualny u»ytkownik (w nazwie preks USER). Tabela powstaªa na podstawie Table 4-4 Views With Information Specic to Partitioned

Tables and Indexes [12].

Perspektywa

Opis

DBA_PART_TABLES

Wy±wietla informacje dotycz¡ce wszystkich tabel partycjonowanych, np. metoda partycjonowania, status, liczba partycji, domy±lne warto±ci parametrów skªadowania.

DBA_TAB_PARTITIONS

Podaje informacje o poszczególnych partycjach tabel, takie jak: warto±ci parametrów skªadowania, statystyki (DBMS_STATS).

DBA_TAB_SUBPARTITIONS

Podaje informacje o poszczególnych podpartycjach tabel, takie jak: warto±ci parametrów skªadowania, statystyki (DBMS_STATS).

DBA_PART_KEY_COLUMNS

Wskazuje klucze partycjonowania poszczególnych partycjnowanych obiektów (tabel lub indeksów).

DBA_SUBPART_KEY_COLUMNS

Wskazuje

klucze

podpartycji

poszczególnych

obiektów (tabel lub indeksów) partycjonowanych dwupoziomowo. DBA_PART_COL_STATISTICS

Przedstawia statystyki partycji dotycz¡ce kolumn, wskazuje na rodzaj zebranych statystyk oraz informuje o typie lub braku histogramu.

DBA_SUBPART_COL_STATISTICS

Przedstawia statystyki podpartycji dotycz¡ce kolumn, wskazuje na rodzaj zebranych statystyk oraz informuje o typie lub braku histogramu.

27

DBA_PART_HISTOGRAMS

Przedstawia dane stworzonych histogramów dla danej partycji.

DBA_SUBPART_HISTOGRAMS

Przedstawia dane stworzonych histogramów dla danej podpartycji.

DBA_PART_INDEXES

Wy±wietla informacje dotycz¡ce wszystkich indeksów partycjonowanych, np. metoda partycjonowania, typ indeksu, liczba partycji, domy±lne warto±ci parametrów skªadowania.

DBA_IND_PARTITIONS

Podaje informacje dotycz¡ce poszczególnych partycji indeksów, takie jak: status, warto±ci parametrów skªadowania, statystyki (DBMS_STATS).

DBA_IND_SUBPARTITIONS

Podaje informacje dotycz¡ce poszczególnych podpartycji indeksów, takie jak: status, warto±ci parametrów skªadowania, statystyki (DBMS_STATS).

DBA_SUBPARTITION_TEMPLATES Podaje informacje dotycz¡ce istniej¡cych szablonów padpartycji.

28

3

‘rodowisko testów opcji partycjonowania

3.1 Cel i zakres testów Testy maj¡ na celu sprawdzenie efektywno±ci opcji partycjonowania tabel i indeksów w Oracle Database 11gR2 przy uwzgl¦dnieniu ró»nych rozmiarów danych testowych. Pod uwag¦ zostaªy wzi¦te ró»ne techniki partycjonowania bazuj¡ce na tym samym modelu relacyjnym. Efektywno±¢ zostaªa mierzona przy pomocy aplikacji testowej, która ª¡czy si¦ z wybran¡ baz¡ danych oraz wskazuje czas odpowiedzi na wyniki zapyta« typu SELECT.

3.2 Opis ±rodowiska testowego Badania zostaªy przeprowadzone przy u»yciu trzech maszyn wirtualnych, do których mo»na uzyska¢ dost¦p poprzez wydziaªowy serwer galera.ii.pw.edu.pl. Dwie maszyny orem1.ii.pw.edu.pl oraz orem2.ii.pw.edu.pl pracuj¡ pod kontrol¡ systemu Oracle Linux Server release 6.4. Na nich zostaªo zainstalowane oprogramowanie Oracle Database Enterprise Edition 11gR2 z opcj¡ partycjonowania oraz utworzone testowe bazy danych. Trzecia maszyna orem5.ii.pw.edu.pl z systemem Windows XP peªni charakter serwera aplikacyjnego ª¡cz¡cego si¦ z bazami danych z orem1 lub orem2 (na orem5 zostaªa stworzona oraz wykonywana aplikacja testowa). Inne wa»ne narz¦dzia z których jeszcze korzystaªam w trakcie pisania pracy, to:



PuTTY release 0.60 - wykorzystywany do ª¡czenia si¦ przez protokóª SSH z serwerem galera.ii.pw.edu.pl, z którego nast¦pnie uzyskiwano poª¡czenie przez ssh z maszynami wirtualnymi orem1, orem2 oraz orem5;



Xming X Server for Windows - umo»liwia zdalny dost¦p w sesji gracznej przy u»yciu PuTTy;



Database Conguration Assistant (DBCA) - utworzenie baz danych;



Oracle Net Manager (netmgr)  konguracja procesów nasªuchuj¡cych ang. listener umo»liwiaj¡cych zdalne ª¡czenie z bazami danych przez sie¢;



Eclipse IDE for Java EE Developers - ±rodowisko programistyczne przeznaczone do j¦zyka Java, w którym zostaªa napisana aplikacja testuj¡ca;

29

Rysunek 10: Lista gªównych parametrów konguracyjnych wygenerowana przez narz¦dzie DBCA przy okazji tworzenia bazy danych dbtest na maszynie orem1.

30

Na ka»dej z linuxowych maszyn wirtualnych przy u»yciu narz¦dzia Database Conguration Assistant (DBCA) zostaªy utworzone bazy danych z pojedynczymi instancjami. Przy ich tworzeniu skorzystaªam z jednego z dost¦pnych szablonów - General Purpose or Transaction Processing dotycz¡cego bazy danych ogólnego przeznaczania. Oznacza to, »e ka»da z baz zostaªa utworzona z takimi samymi ustawieniami konguracyjnymi (warto±ci gªównych parametrów znajduj¡ si¦ na powy»szym obrazku). Lokalne nazwy (ORACLE_SID) tych baz danych to odpowiednio dla orem1 i orem2 dbtest i dbtest2.

3.3 Relacyjny model danych Poni»ej przedstawiony jest wyj±ciowy relacyjny model danych, który stanowiª baz¦ do tworzenia kolejnych jego wariacji uwzgl¦dniaj¡cych ró»ne techniki partycjonowania tabel oraz indeksów. Model skªada si¦ z dwóch tabel, nadrz¦dnej KLIENCI oraz podrz¦dnej ZAMOWIENIA. Warto zwróci¢ uwag¦ na fakt, i» tabela ZAMO-

WIENIA zawiera kolumn¦ wirtualn¡ region tworzon¡ na podstawie klucza gªównego id_zamowienia. Do tabeli ZAMOWIENIA zostaªy równie» dodane indeksy bitmapowy na kolumnie region oraz drzewiasty na kluczu obcym id_klienta, które b¦d¡ poddawane partycjonowaniu.

Rysunek 11: Diagram relacyjny przedstawiaj¡cy bazowy model danych. Opracowanie wªasne.

31

Listing 11: Polecenie tworz¡ce niepartycjonowan¡ tabel¦ KLIENCI.

CREATE TABLE klienci ( id_klienta NUMBER (15) NOT NULL , nazwisko VARCHAR2 (25) NOT NULL , imie VARCHAR2 (15) NOT NULL , miasto VARCHAR2 (20) NOT NULL , kod NUMBER (6) NOT NULL , adres VARCHAR2 (30) NOT NULL ) TABLESPACE TB_KLIENCI ; alter table klienci add constraint klienci_pk primary key ( id_klienta ) using index TABLESPACE IND_KLIENCI ;

Listing 12: Polecenie tworz¡ce niepartycjonowan¡ tabel¦ ZAMOWIENIA

CREATE TABLE zamowienia ( id_zamowienia VARCHAR2 (25) NOT NULL , data_zam DATE NOT NULL , kwota NUMBER (6 ,2) NOT NULL , id_klienta NUMBER (15) NOT NULL , region AS ( case when substr ( id_zamowienia ,1 ,1) = 'N ' then ' NORTH ' when substr ( id_zamowienia ,1 ,1) = 'E ' then ' EAST ' when substr ( id_zamowienia ,1 ,1) = 'S ' then ' SOUTH ' when substr ( id_zamowienia ,1 ,1) = 'W ' then ' WEST ' when substr ( id_zamowienia ,1 ,1) = 'C ' then ' CENTER ' end ) , CONSTRAINT zamowienia_pk PRIMARY KEY ( id_zamowienia ) , CONSTRAINT klient_zam_fk FOREIGN KEY ( id_klienta ) REFERENCES klienci ( id_klienta )) TABLESPACE TB_ZAM ;

32

Listing 13: Polecenie tworz¡ce dodatkowe niepartycjonowane indeksy na tabeli za-

mowienia

CREATE BITMAP INDEX zam_bitmap_ind ON zamowienia ( region ) TABLESPACE IND_ZAM ; CREATE INDEX zam_fk_ind ON zamowienia ( id_klienta ) TABLESPACE IND_ZAM ; Listing 14: Polecenie tworz¡ce indeks globalnie partycjonowany metod¡ zakresow¡ na kluczu obcym id_klienta tabeli zamowienia (w odniesieniu do tabeli klienci maj¡cej 60 mln wierszy)

CREATE INDEX zam_fk_ind ON zamowienia ( id_klienta ) GLOBAL PARTITION BY RANGE ( id_klienta ) ( PARTITION p1 VALUES LESS THAN (7500000) , PARTITION p2 VALUES LESS THAN (15000000) , PARTITION p3 VALUES LESS THAN (22500000) , PARTITION p4 VALUES LESS THAN (30000000) , PARTITION p5 VALUES LESS THAN (37500000) , PARTITION p6 VALUES LESS THAN (45000000) , PARTITION p7 VALUES LESS THAN (52500000) , PARTITION p_greater VALUES LESS THAN ( maxvalue )) TABLESPACE IND_ZAM PARALLEL NOLOGGING ;

Listing 15: Indeks globalny partycjonowany zakresowo tabeli zamowienia

SQL > SELECT partition_name , num_rows , high_value FROM dba_ind_partitions WHERE index_name = ' ZAM_FK_IND '; PARTITION_NAME

NUM_ROWS HIGH_VALUE

------------------------ ---------- -----------------P1

22777687 7500000

P2

22749614 15000000

P3

22733538 22500000

P4

21421454 30000000

P5

7455619

37500000

P6

7280534

45000000

P7

7354128

52500000

P_GREATER

7253998

MAXVALUE 33

W nast¦pnych podrozdziaªach zostan¡ przedstawione skrypty tworz¡ce partycjonowane tabele i indesy, które zostaªy uwzgl¦dnione w testach wraz z informacj¡ do schematu której bazy danych nale»¡. Tabele klienci oraz zamowienia niepartycjonowane s¡ skªadowane w bazie dbtest na orem1. Zaprezentowane równie» b¦d¡ wyniki zapyta« skierowanych do odpowiednich perspektyw pokazuj¡ce rozkªad danych w poszczególnych partycjach tabel czy indeksów.

3.3.1

Partycjonowanie referencyjne (orem1)

Tabela ZAMOWIENIA_REF zostaªa partycjonowana na wzór (partycjonowanie referencyjne) tabeli KLIENCI_REF, która jest przykªadem partycjonowania listowego wedªug kolumny miasto. Ka»da z tabel zostaªa podzielona na 5 partycji oraz wraz z indeksami jest skªadowana w bazie danych dbtest na maszynie orem1. Tabele te byªy testowane w dwóch konguracjach indeksowych:



tylko z niepartycjonowanymi indeksami na kluczach gªównych;



z niepartycjonowanymi indeksami na kluczach gªównych oraz dla tabeli ZA-

MOWIENIA_REF partycjonowanymi lokalnie indeksami bitmapowym na kolumnie region oraz drzewiastym na kluczu obcym id_klienta.

Listing 16: Polecenie tworz¡ce tabel¦ klienci_ref partycjonowan¡ listowo oraz tabel¦

zamowienia_ref partycjonowan¡ referencyjnie

CREATE TABLE klienci_ref ( id_klienta NUMBER (15) NOT NULL , nazwisko VARCHAR2 (25) NOT NULL , imie VARCHAR2 (15) NOT NULL , miasto VARCHAR2 (20) NOT NULL , kod NUMBER (6) NOT NULL , adres VARCHAR2 (30) NOT NULL ) PARTITION BY LIST ( miasto ) ( PARTITION klienci_east VALUES ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ') , PARTITION klienci_west VALUES ( ' WROCLAW ' , ' OPOLE ' , ' LEGNICA ' , ' ZIELONA GORA ') , PARTITION klienci_center 34

VALUES ( ' LODZ ' , ' POZNAN ' , ' BYDGOSZCZ ' , ' TORUN ') , PARTITION klienci_north VALUES ( ' SZCZECIN ' , ' KOSZALIN ' , ' GDANSK ' , ' GDYNIA ' , ' OLSZTYN ') , PARTITION klienci_south VALUES ( ' KATOWICE ' , ' KRAKOW ' , ' RZESZOW ' , ' KIELCE ')) TABLESPACE TB_REF PARALLEL ; alter table klienci_ref add constraint klient_ref_pk primary key ( id_klienta ) using index global TABLESPACE TB_IND_REF ; CREATE TABLE zamowienia_ref ( id_zamowienia VARCHAR2 (25) NOT NULL , data_zam DATE NOT NULL , kwota NUMBER (6 ,2) NOT NULL , id_klienta NUMBER (15) NOT NULL , region AS ( case when substr ( id_zamowienia ,1 ,1) = 'N ' then ' NORTH ' when substr ( id_zamowienia ,1 ,1) = 'E ' then ' EAST ' when substr ( id_zamowienia ,1 ,1) = 'S ' then ' SOUTH ' when substr ( id_zamowienia ,1 ,1) = 'W ' then ' WEST ' when substr ( id_zamowienia ,1 ,1) = 'C ' then ' CENTER ' end ) , CONSTRAINT klient_zam_ref_fk FOREIGN KEY ( id_klienta ) REFERENCES klienci_ref ( id_klienta )) PARTITION BY REFERENCE ( klient_zam_ref_fk ) TABLESPACE TB_REF PARALLEL ; alter table zamowienia_ref add constraint zam_ref_pk primary key ( id_zamowienia ) using index global TABLESPACE TB_IND_REF ;

Listing 17: Polecenie tworz¡ce partycjonowane lokalnie indeksy tabeli zamowie-

nia_ref.

CREATE BITMAP INDEX zam_ref_bitmap ON zamowienia_ref ( region ) TABLESPACE TB_IND_REF LOCAL PARALLEL NOLOGGING ; CREATE INDEX zam_ref_fk ON zamowienia_ref ( id_klienta ) LOCAL TABLESPACE TB_IND_REF PARALLEL NOLOGGING ;

35

Listing 18: Rozkªad danych mi¦dzy partycje tabel klienci_ref (60 mln wierszy) i

zamowienia_ref (120 mln wierszy)

SQL > SELECT

partition_name , num_rows ,

high_value FROM dba_tab_partitions WHERE table_name = ' KLIENCI_REF '; PARTITION_NAME

NUM_ROWS

HIGH_VALUE

--------------- ---------- ------------- -------------------- ------------------KLIENCI_CENTER

11428570

' LODZ ' , ' POZNAN ' , ' BYDGOSZCZ ' , ' TORUN '

KLIENCI_EAST

11428572

' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM '

KLIENCI_NORTH

14285714

' SZCZECIN ' , ' KOSZALIN ' , ' GDANSK ' , ' GDYNIA ' , ' OLSZTYN '

KLIENCI_SOUTH

11428572

' KATOWICE ' , ' KRAKOW ' , ' RZESZOW ' , ' KIELCE '

KLIENCI_WEST

11428572

' WROCLAW ' , ' OPOLE ' , ' LEGNICA ' , ' ZIELONA GORA '

SQL > SELECT

partition_name , num_rows FROM dba_tab_partitions

WHERE table_name = ' ZAMOWIENIA_REF '; PARTITION_NAME

NUM_ROWS

-------------------------- ---------KLIENCI_CENTER

22860093

KLIENCI_EAST

22854570

KLIENCI_NORTH

28564512

KLIENCI_SOUTH

22863576

KLIENCI_WEST

22857249

Listing 19: Indeksy lokalne tabeli zamowienia_ref

SQL > SELECT partition_name , num_rows FROM dba_ind_partitions WHERE index_name = ' ZAM_REF_FK '; PARTITION_NAME

NUM_ROWS

------------------------------ ---------KLIENCI_CENTER

23432401

KLIENCI_EAST

23755607

KLIENCI_NORTH

29502361

KLIENCI_SOUTH

23328675

KLIENCI_WEST

22857756

SQL > SELECT partition_name , num_rows FROM dba_ind_partitions WHERE index_name = ' ZAM_REF_BITMAP '; PARTITION_NAME

NUM_ROWS

------------------------------ ---------KLIENCI_CENTER

4482

36

KLIENCI_EAST

4481

KLIENCI_NORTH

5598

KLIENCI_SOUTH

4482

KLIENCI_WEST

4480

3.3.2

Partycjonowanie mieszaj¡ce (orem2)

Tabele KLIENCI_HASH oraz ZAMOWIENIA_HASH zostaªy poddane partycjonowaniu mieszaj¡cemu wedªug kolumny id_klienta, co potencjalnie mo»e by¢ opªacalne przy zapytaniach bazuj¡cych na ich zª¡czeniach. Ka»da z tabel zostaªa podzielona na 8 partycji. Obie tabele wraz z indeksami znajduj¡ si¦ w bazie danych dbtest2 na maszynie orem2. Tabele te byªy testowane w nast¦puj¡cych konguracjach indeksowych:



tylko z niepartycjonowanymi indeksami na kluczach gªównych;



z niepartycjonowanymi indeksami na kluczach gªównych oraz dla tabeli ZA-

MOWIENIA_HASH partycjonowanymi lokalnie indeksami bitmapowym na kolumnie region oraz drzewiastym na kluczu obcym id_klienta ;



z niepartycjonowanymi indeksami na kluczach gªównych oraz dla tabeli ZA-

MOWIENIA_HASH partycjonowanym lokalnie indeksem bitmapowym na kolumnie region oraz drzewiastym globalnym niepartycjonowanym utworzonym na kluczu obcym id_klienta ;



z niepartycjonowanymi indeksami na kluczach gªównych oraz dla tabeli ZA-

MOWIENIA_HASH partycjonowanym lokalnie indeksem bitmapowym na kolumnie region oraz preksowanym globalnym drzewiastym partycjonowanym zakresowo na kluczu obcym id_klienta.

Listing 20: Polecenie tworz¡ce tabel¦ klienci_hash oraz zamowienia_hash partycjonowane metod¡ mieszaj¡c¡

CREATE TABLE klienci_hash ( id_klienta NUMBER (15) NOT NULL , nazwisko VARCHAR2 (25) NOT NULL , imie VARCHAR2 (15) NOT NULL , miasto VARCHAR2 (20) NOT NULL , kod NUMBER (6) NOT NULL ,

37

adres VARCHAR2 (30) NOT NULL ) PARTITION BY HASH ( id_klienta ) PARTITIONS 8 TABLESPACE TB_K_HASH ; alter table klienci_hash add constraint klient_hash_pk primary key ( id_klienta ) using index global TABLESPACE IND_KLIENCI ; CREATE TABLE zamowienia_hash ( id_zamowienia VARCHAR2 (25) NOT NULL , data_zam DATE NOT NULL , kwota NUMBER (6 ,2) NOT NULL , id_klienta NUMBER (15) NOT NULL , region AS ( case when substr ( id_zamowienia ,1 ,1) = 'N ' then ' NORTH ' when substr ( id_zamowienia ,1 ,1) = 'E ' then ' EAST ' when substr ( id_zamowienia ,1 ,1) = 'S ' then ' SOUTH ' when substr ( id_zamowienia ,1 ,1) = 'W ' then ' WEST ' when substr ( id_zamowienia ,1 ,1) = 'C ' then ' CENTER ' end ) , CONSTRAINT klient_zam_hash_fk FOREIGN KEY ( id_klienta ) REFERENCES klienci_hash ( id_klienta )) PARTITION BY HASH ( id_klienta ) PARTITIONS 8 TABLESPACE TB_K_HASH ; alter table zamowienia_hash add constraint zam_hash_pk primary key ( id_zamowienia ) using index global TABLESPACE IND_ZAM ; Listing 21: Polecenia tworz¡ce partycjonowane lokalnie indeksy tabeli zamowie-

nia_hash.

CREATE INDEX zam_hash_fk ON zamowienia_hash ( id_klienta ) LOCAL TABLESPACE IND_ZAM PARALLEL NOLOGGING ; CREATE BITMAP INDEX zam_hash_bitmap ON zamowienia_hash ( region ) LOCAL PARALLEL TABLESPACE IND_ZAM NOLOGGING ; 38

Listing 22: Skrypt tworz¡cy globalny niepartycjonowany indeks tabeli zamowie-

nia_hash.

CREATE INDEX zam_hash_fk ON zamowienia_hash ( id_klienta ) GLOBAL TABLESPACE IND_ZAM NOLOGGING ;

Listing 23: Polecenie tworz¡ce globalny partycjonowany zakresowo indeks tabeli za-

mowienia_hash (gdy tabela klienci_hash zawieraªa 30mln wierszy).

CREATE INDEX zam_hash_fk ON zamowienia_hash ( id_klienta ) GLOBAL PARTITION BY RANGE ( id_klienta ) ( PARTITION p1 VALUES LESS THAN (3750000) , PARTITION p2 VALUES LESS THAN (7500000) , PARTITION p3 VALUES LESS THAN (11250000) , PARTITION p4 VALUES LESS THAN (15000000) , PARTITION p5 VALUES LESS THAN (18750000) , PARTITION p6 VALUES LESS THAN (22500000) , PARTITION p7 VALUES LESS THAN (26250000) , PARTITION p_greater VALUES LESS THAN ( maxvalue ) ) TABLESPACE IND_ZAM PARALLEL NOLOGGING ;

Listing 24: Rozkªad danych mi¦dzy partycje tabel klienci_hash i zamowienia_hash (po 60 mln wierszy)

SQL > SELECT

partition_name , num_rows FROM dba_tab_partitions

WHERE table_name = ' KLIENCI_HASH '; PARTITION_NAME

NUM_ROWS

-------------------------- ---------SYS_P41

7500299

SYS_P42

7498104

SYS_P43

7502604

SYS_P44

7495839

SYS_P45

7497233

SYS_P46

7499631

SYS_P47

7503399

SYS_P48

7502891

39

SQL > SELECT

partition_name , num_rows FROM dba_tab_partitions

WHERE table_name = ' ZAMOWIENIA_HASH '; PARTITION_NAME

NUM_ROWS

--------------------------- ---------SYS_P101

7504835

SYS_P102

7501024

SYS_P103

7500795

SYS_P104

7495734

SYS_P105

7499738

SYS_P106

7495923

SYS_P107

7503046

SYS_P108

7498905

Listing 25: Indeks lokalny ZAM_HASH_FK tabeli zamowienia_hash

SQL > SELECT partition_name , num_rows FROM dba_ind_partitions WHERE index_name = ' ZAM_HASH_FK '; PARTITION_NAME

NUM_ROWS

------------------------------ ---------SYS_P209

7218192

SYS_P210

7590410

SYS_P211

7380034

SYS_P212

7841330

SYS_P213

7401678

SYS_P214

7660292

SYS_P215

7533011

SYS_P216

7663615

Listing 26: Indeks globalny partycjonowany zakresowo tabeli zamowienia_hash (gdy

klienci_hash miaªa 30 mln wierszy)

SQL > SELECT partition_name , num_rows , high_value FROM dba_ind_partitions WHERE index_name = ' ZAM_HASH_FK '; PARTITION_NAME

NUM_ROWS HIGH_VALUE

-------------- --------

----------

P1

7427314

3750000

P2

7501872

7500000

P3

7475270

11250000

P4

7244029

15000000 40

P5

7533282

18750000

P6

7374100

22500000

P7

7509397

26250000

P_GREATER

7208202

MAXVALUE

3.3.3

Partycjonowanie na kolumnie wirtualnej (orem2)

Tabela ZAMOWIENIA_LIST zostaªa partycjonowana listowo. Kluczem partycjonowania jest kolumna wirtualna region. Tabela zostaªa podzielona na 5 partycji, wraz z indeksami nale»y do bazy danych dbtest2 na maszynie orem2. Tabela ZAMOWIENIA_LIST byªa testowana w nast¦puj¡cych konguracjach indeksowych:



tylko z niepartycjonowanym indeksem na kluczu gªównym;



z niepartycjonowanymi globalnymi indeksami na kluczu gªównym oraz na kluczu obcym id_klienta ;



z niepartycjonowanym globalnym indeksem na kluczu gªównym oraz partycjonowanym lokalnie indeksem na kluczu obcym id_klienta ;



z niepartycjonowanym globalnym indeksem na kluczu gªównym oraz globalnym preksowanym partycjonowanym metod¡ mieszaj¡c¡ na kluczu obcym

id_klienta.

Listing 27: Polecenie tworz¡ce tabel¦ zamowienia_list partycjonowan¡ metod¡ listow¡.

CREATE TABLE zamowienia_list ( id_zamowienia VARCHAR2 (25) NOT NULL , data_zam DATE NOT NULL , kwota NUMBER (6 ,2) NOT NULL , id_klienta NUMBER (15) NOT NULL , region AS ( case when substr ( id_zamowienia ,1 ,1) = 'N ' then ' NORTH ' when substr ( id_zamowienia ,1 ,1) = 'E ' then ' EAST ' when substr ( id_zamowienia ,1 ,1) = 'S ' then ' SOUTH ' when substr ( id_zamowienia ,1 ,1) = 'W ' then ' WEST ' when substr ( id_zamowienia ,1 ,1) = 'C ' then ' CENTER ' end ) ,

41

CONSTRAINT klient_zam_list_fk FOREIGN KEY ( id_klienta ) REFERENCES klienci_hash ( id_klienta )) PARTITION BY LIST ( region ) ( PARTITION zam_west VALUES ( ' WEST ') , PARTITION zam_east VALUES ( ' EAST ') , PARTITION zam_central VALUES ( ' CENTER ') , PARTITION zam_north VALUES ( ' NORTH ') , PARTITION zam_south VALUES ( ' SOUTH ') ) TABLESPACE ZAM_TB PARALLEL ; alter table zamowienia_list add constraint zam_list_pk primary key ( id_zamowienia ) using index global TABLESPACE IND_ZAM ;

Listing 28: Polecenie tworz¡ce partycjonowany lokalnie indeks na kluczu obcym

id_klienta tabeli zamowienia_list.

CREATE INDEX zam_list_fk ON zamowienia_list ( id_klienta ) LOCAL TABLESPACE IND_ZAM PARALLEL NOLOGGING ;

Listing 29: Polecenie tworz¡ce globalny niepartycjonowany indeks tabeli zamowie-

nia_list.

CREATE INDEX zam_list_fk ON zamowienia_list ( id_klienta ) GLOBAL TABLESPACE IND_ZAM NOLOGGING ;

Listing 30: Rozkªad danych mi¦dzy partycje tabeli zamowienia_list (dla 120mln wierszy).

SQL > SELECT

partition_name , num_rows , high_value FROM dba_tab_partitions

WHERE table_name = ' ZAMOWIENIA_LIST '; PARTITION_NAME

NUM_ROWS

HIGH_VALUE

------------------- ---------- -----------------------------------------ZAM_CENTRAL

24000096

' CENTER '

ZAM_EAST

23993296

' EAST '

ZAM_NORTH

24002670

' NORTH '

ZAM_SOUTH

24006678

' SOUTH '

ZAM_WEST

23997260

' WEST '

42

Listing 31: Indeks lokalny zam_list_fk tabeli zamowienia_list.

SQL > SELECT

WHERE index_name = ' ZAM_LIST_FK ';

PARTITION_NAME

NUM_ROWS

------------------------------ ---------ZAM_CENTRAL

23317979

ZAM_EAST

23097547

ZAM_NORTH

24128378

ZAM_SOUTH

23782057

ZAM_WEST

23673529

Listing 32: Indeks globalny partycjonowany metod¡ mieszaj¡c¡ tabeli zamowie-

nia_list (gdy klienci_hash miaªa 60 mln wierszy).

SQL > SELECT partition_name , num_rows FROM dba_ind_partitions WHERE index_name = ' ZAM_LIST_FK '; PARTITION_NAME

NUM_ROWS

------------------------------ ---------SYS_P509

13949878

SYS_P510

15236847

SYS_P511

15071437

SYS_P512

14400264

SYS_P513

15419528

SYS_P514

15246985

SYS_P515

15635793

SYS_P516

15245726

3.3.4

Partycjonowanie interwaªowe (orem2)

Tabela ZAMOWIENIA_INTER zostaªa partycjonowana interwaªowo, wedªug kolumny data_zam (12 partycji, ka»da zawiera dane z innego miesi¡ca 2014 roku). Tabela wraz z indeksami nale»y do bazy danych dbtest2 na maszynie orem2. Tabela ZAMOWIENIA_INTER byªa testowana w nast¦puj¡cych konguracjach indeksowych:



tylko z niepartycjonowanym indeksem na kluczu gªównym;



z niepartycjonowanymi globalnymi indeksami na kluczu gªównym oraz na kluczu obcym id_klienta oraz lokalnie partycjonowanym bitmapowym indeksem na kolumnie region ;

43



z niepartycjonowanym globalnym indeksem na kluczu gªównym oraz partycjonowanym lokalnie indeksem na kluczu obcym id_klienta oraz równie» lokalnie partycjonowanym bitmapowym indeksem na kolumnie region ;



z niepartycjonowanym globalnym indeksem na kluczu gªównym oraz globalnym preksowanym partycjonowanym metod¡ mieszaj¡c¡ na kluczu obcym

id_klienta i lokalnie partycjonowanym bitmapowym indeksem na kolumnie region.

Listing 33: Skrypt tworz¡cy tabel¦ zamowienia_inter partycjonowan¡ metod¡ interwaªow¡.

CREATE TABLE zamowienia_inter ( id_zamowienia VARCHAR2 (25) NOT NULL , data_zam DATE NOT NULL , kwota NUMBER (6 ,2) NOT NULL , id_klienta NUMBER (15) NOT NULL , region AS ( case when substr ( id_zamowienia ,1 ,1) = 'N ' then ' NORTH ' when substr ( id_zamowienia ,1 ,1) = 'E ' then ' EAST ' when substr ( id_zamowienia ,1 ,1) = 'S ' then ' SOUTH ' when substr ( id_zamowienia ,1 ,1) = 'W ' then ' WEST ' when substr ( id_zamowienia ,1 ,1) = 'C ' then ' CENTER ' end ) , CONSTRAINT klient_zam_inter_fk FOREIGN KEY ( id_klienta ) REFERENCES klienci_hash ( id_klienta )) PARTITION BY RANGE ( data_zam ) INTERVAL ( NUMTOYMINTERVAL (1 , ' MONTH ')) ( PARTITION sty2014 VALUES LESS THAN ( TO_DATE ( '1 -02 -2014 ' , 'DD - MM - YYYY ')) ) TABLESPACE ZAM_TB PARALLEL ; alter table zamowienia_inter add constraint zam_inter_pk primary key ( id_zamowienia ) using index global TABLESPACE IND_ZAM ;

Listing 34: Polecenie tworz¡ce partycjonowane lokalnie indeksy tabeli zamowie-

nia_inter.

44

CREATE INDEX zam_inter_fk ON zamowienia_inter ( id_klienta ) LOCAL TABLESPACE IND_ZAM PARALLEL NOLOGGING ; CREATE BITMAP INDEX zam_inter_bitmap ON zamowienia_inter ( region ) LOCAL PARALLEL TABLESPACE IND_ZAM NOLOGGING ;

Listing 35: Polecenie tworz¡ce globalny niepartycjonowany indeks tabeli zamowie-

nia_inter.

CREATE INDEX zam_inter_fk ON zamowienia_inter ( id_klienta ) GLOBAL TABLESPACE IND_ZAM NOLOGGING ;

Listing 36: Skrypt tworz¡cy globalny partycjonowany metod¡ mieszaj¡c¡ indeks tabeli zamowienia_inter.

CREATE INDEX zam_inter_fk on zamowienia_inter ( id_klienta ) GLOBAL PARTITION BY HASH ( id_klienta ) PARTITIONS 8 TABLESPACE IND_ZAM PARALLEL NOLOGGING ;

Listing 37: Rozkªad danych mi¦dzy partycje tabeli zamowienia_inter (dla 60mln wierszy).

SQL > SELECT

partition_name , num_rows , high_value FROM dba_tab_partitions

WHERE table_name = ' ZAMOWIENIA_INTER '; PARTITION_NAME

NUM_ROWS HIGH_VALUE

--------------- ------- -- -- --- -- --- --- -- --- --- -- --- --- -- --- --- -- --- -- --- --- -- STY2014

5080479 TO_DATE ( ' 2014 -02 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P189

4589110 TO_DATE ( ' 2014 -03 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P190

5080357 TO_DATE ( ' 2014 -08 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P191

5081236 TO_DATE ( ' 2014 -09 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P192

5083158 TO_DATE ( ' 2014 -11 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P193

5079152 TO_DATE ( ' 2014 -06 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P194

4923316 TO_DATE ( ' 2014 -07 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P195

5082742 TO_DATE ( ' 2015 -01 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P196

4921914 TO_DATE ( ' 2014 -05 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P197

4916954 TO_DATE ( ' 2014 -12 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS 45

SYS_P198

4916023 TO_DATE ( ' 2014 -10 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

SYS_P199

5081875 TO_DATE ( ' 2014 -04 -01 00:00:00 ' , ' SYYYY - MM - DD HH24 : MI : SS

Listing 38: Indeksy lokalne tabeli zamowienia_inter (dla 120 mln wierszy).

SQL > SELECT partition_name , num_rows FROM dba_ind_partitions WHERE index_name = ' ZAM_INTER_FK '; PARTITION_NAME

NUM_ROWS

------------------------------ ---------STY2014

10192195

SYS_P581

9431365

SYS_P582

10023925

SYS_P583

9807155

SYS_P584

10250801

SYS_P585

9971679

SYS_P586

9993482

SYS_P587

10214292

SYS_P588

10156418

SYS_P589

10255595

SYS_P590

10118726

SYS_P591

10122842

SQL > SELECT partition_name , num_rows FROM dba_ind_partitions WHERE index_name = ' ZAM_INTER_BITMAP '; PARTITION_NAME

NUM_ROWS

---------------- -------STY2014

2422

SYS_P481

1900

SYS_P482

1999

SYS_P483

1965

SYS_P484

1997

SYS_P485

1966

SYS_P486

1997

SYS_P487

1999

SYS_P488

1965

SYS_P489

2000

SYS_P490

1965

SYS_P491

2000

46

Listing 39: Indeks globalny partycjonowany metod¡ mieszaj¡c¡ tabeli zamowie-

nia_inter (gdy klienci_hash miaªa 60 mln wierszy).

SQL > SELECT partition_name , num_rows FROM dba_ind_partitions WHERE index_name = ' ZAM_INTER_FK '; PARTITION_NAME

NUM_ROWS

------------------------------ ---------SYS_P501

15554913

SYS_P502

15470661

SYS_P503

14984925

SYS_P504

14132895

SYS_P505

15250336

SYS_P506

15295063

SYS_P507

15048292

SYS_P508

15061026

3.3.5

Partycjonowanie dwupoziomowe interwaªowo-listowe (orem2)

Tabela ZAM_INTER_LIST zostaªa partycjonowana dwupoziomowo, interwaªowo na podstawie kolumny data_zam (12 partycji) i nast¦pnie listowo wedªug kolumny wirtualnej region (po 5 subpartycji na ka»d¡ partycj¦ tabeli). Tabela wraz z indeksami nale»y do bazy danych dbtest2 na maszynie orem2. Tabela ZAM_INTER_LIST byªa testowana w nast¦puj¡cych konguracjach indeksowych:



tylko z niepartycjonowanym indeksem na kluczu gªównym;



z niepartycjonowanymi globalnymi indeksami na kluczu gªównym oraz na kluczu obcym id_klienta ;



z niepartycjonowanym globalnym indeksem na kluczu gªównym oraz partycjonowanym dwupoziomowym lokalnym indeksem na kluczu obcym id_klienta ;



z niepartycjonowanym globalnym indeksem na kluczu gªównym oraz globalnym preksowanym partycjonowanym metod¡ zakresow¡ na kluczu obcym

id_klienta.

47

Listing 40: Skrypt tworz¡cy tabel¦ zam_inter_list partycjonowan¡ dwupoziomowo interwaªowo-listow¡.

CREATE TABLE zam_inter_list ( id_zamowienia VARCHAR2 (25) NOT NULL , data_zam DATE NOT NULL , kwota NUMBER (6 ,2) NOT NULL , id_klienta NUMBER (15) NOT NULL , region AS ( case when substr ( id_zamowienia ,1 ,1) = 'N ' then ' NORTH ' when substr ( id_zamowienia ,1 ,1) = 'E ' then ' EAST ' when substr ( id_zamowienia ,1 ,1) = 'S ' then ' SOUTH ' when substr ( id_zamowienia ,1 ,1) = 'W ' then ' WEST ' when substr ( id_zamowienia ,1 ,1) = 'C ' then ' CENTER ' end ) , CONSTRAINT klient_zam_inter_list_fk FOREIGN KEY ( id_klienta ) REFERENCES klienci_hash ( id_klienta )) PARTITION BY RANGE ( data_zam ) INTERVAL ( NUMTOYMINTERVAL (1 , ' MONTH ')) SUBPARTITION BY LIST ( region ) SUBPARTITION TEMPLATE ( SUBPARTITION sp_N VALUES ( ' NORTH ') , SUBPARTITION sp_E VALUES ( ' EAST ') , SUBPARTITION sp_S VALUES ( ' SOUTH ') , SUBPARTITION sp_W VALUES ( ' WEST ') , SUBPARTITION sp_C VALUES ( ' CENTER ')) ( PARTITION p1_data VALUES LESS THAN ( TO_DATE ( '1 -02 -2014 ' , 'DD - MM - YYYY ')) ) TABLESPACE ZAM_TB PARALLEL ; alter table zam_inter_list add constraint zam_inter_list_pk primary key ( id_zamowienia ) using index global TABLESPACE IND_ZAM ;

Listing 41: Polecenie tworz¡ce partycjonowany lokalnie indeks na kluczu obcym

id_klienta tabeli zam_inter_list.

CREATE INDEX zam_inter_list_fk ON zamowienia_inter_list ( id_klienta ) LOCAL TABLESPACE IND_ZAM PARALLEL NOLOGGING ; 48

Listing

42:

Polecenie

tworz¡ce

globalny

niepartycjonowany

indeks

tabeli

zam_inter_list.

CREATE INDEX zam_inter_list_fk ON zam_inter_list_fk ( id_klienta ) GLOBAL TABLESPACE IND_ZAM NOLOGGING ;

Listing 43: Skrypt tworz¡cy globalny partycjonowany zakresowo indeks tabeli

zam_inter_list (gdy tabela klienci_hash zawieraªa 30mln wierszy).

CREATE INDEX zam_inter_list_fk ON zam_inter_list ( id_klienta ) GLOBAL PARTITION BY RANGE ( id_klienta ) ( PARTITION p1 VALUES LESS THAN (3750000) , PARTITION p2 VALUES LESS THAN (7500000) , PARTITION p3 VALUES LESS THAN (11250000) , PARTITION p4 VALUES LESS THAN (15000000) , PARTITION p5 VALUES LESS THAN (18750000) , PARTITION p6 VALUES LESS THAN (22500000) , PARTITION p7 VALUES LESS THAN (26250000) , PARTITION p_greater VALUES LESS THAN ( maxvalue )) TABLESPACE IND_ZAM PARALLEL NOLOGGING ;

Listing 44: Rozkªad danych mi¦dzy partycje tabeli zam_inter_list z uwzgl¦dnieniem ilo±ci subpartycji przypadaj¡cych na ka»d¡ z partycji (dla 60 mln wierszy).

SQL > SELECT partition_name , num_rows , subpartition_count , high_value FROM dba_tab_partitions WHERE table_name = ' ZAM_INTER_LIST '; PARTITION_NAME NUM_ROWS SUBPARTITION_COUNT HIGH_VALUE -------------- -------- ------------------ ----------------------------P1_DATA

5080479

5 TO_DATE ( ' 2014 -02 -01 00:00:00 '

SYS_P382

4589110

5 TO_DATE ( ' 2014 -03 -01 00:00:00 '

SYS_P388

5081875

5 TO_DATE ( ' 2014 -04 -01 00:00:00 '

SYS_P394

4921914

5 TO_DATE ( ' 2014 -05 -01 00:00:00 '

SYS_P400

5079152

5 TO_DATE ( ' 2014 -06 -01 00:00:00 '

SYS_P406

4923316

5 TO_DATE ( ' 2014 -07 -01 00:00:00 '

SYS_P412

5080357

5 TO_DATE ( ' 2014 -08 -01 00:00:00 '

SYS_P418

5081236

5 TO_DATE ( ' 2014 -09 -01 00:00:00 '

SYS_P424

4916023

5 TO_DATE ( ' 2014 -10 -01 00:00:00 '

SYS_P430

5083158

5 TO_DATE ( ' 2014 -11 -01 00:00:00 '

SYS_P436

4916954

5 TO_DATE ( ' 2014 -12 -01 00:00:00 '

SYS_P442

5082742

5 TO_DATE ( ' 2015 -01 -01 00:00:00 '

49

Listing 45: Indeks lokalny tabeli zam_inter_list partycjonowany dwupoziomowo.

SQL > SELECT partition_name , num_rows , composite FROM dba_ind_partitions WHERE index_name = ' ZAM_INTER_LIST_FK '; PARTITION_NAME

NUM_ROWS

COM

--------------- ---------- --P1_DATA

5065874

YES

SYS_P461

4521945

YES

SYS_P462

4984444

YES

SYS_P463

4991925

YES

SYS_P464

5097581

YES

SYS_P465

4632332

YES

SYS_P466

5031892

YES

SYS_P467

5090625

YES

SYS_P468

5076736

YES

SYS_P469

5336190

YES

SYS_P470

5144916

YES

SYS_P471

5034303

YES

Listing 46: Indeks globalny partycjonowany zakresowo tabeli zam_inter_list.

SQL > SELECT partition_name , num_rows , composite FROM dba_ind_partitions WHERE index_name = ' ZAM_INTER_LIST_FK '; PARTITION_NAME

NUM_ROWS

COM

--------------- ---------- --P1

7375520

NO

P2

7702527

NO

P3

7007122

NO

P4

7880180

NO

P5

7489088

NO

P6

7367646

NO

P7

7631917

NO

P_GREATER

7542944

NO

3.3.6

Partycjonowanie dwupoziomowe zakresowo-mieszaj¡ce (orem2)

Tabela ZAM_RANGE_HASH zostaªa partycjonowana dwupoziomowo, zakresowo na podstawie kolumny data_zam (12 partycji)) i nast¦pnie metod¡ mieszaj¡c¡ na kluczu obcym id_klienta (po 8 subpartycji na ka»d¡ partycj¦). Tabela wraz z indeksami nale»y do bazy danych dbtest2 na maszynie orem2.

50

Tabela ZAMOWIENIA_INTER byªa testowana w dwóch konguracjach indeksowych:



tylko z niepartycjonowanym indeksem na kluczu gªównym;



z niepartycjonowanym globalnym indeksem na kluczu gªównym oraz dwupoziomowymi partycjonowanymi lokalnie indeksami na kluczu obcym id_klienta oraz bitmapowym na kolumnie region ;

Listing 47: Skrypt tworz¡cy tabel¦ zam_range_hash partycjonowan¡ dwupoziomowo zakresowo-mieszaj¡co.

CREATE TABLE zam_range_hash ( id_zamowienia VARCHAR2 (25) NOT NULL , data_zam DATE NOT NULL , kwota NUMBER (6 ,2) NOT NULL , id_klienta NUMBER (15) NOT NULL , region AS ( case when substr ( id_zamowienia ,1 ,1) = 'N ' then ' NORTH ' when substr ( id_zamowienia ,1 ,1) = 'E ' then ' EAST ' when substr ( id_zamowienia ,1 ,1) = 'S ' then ' SOUTH ' when substr ( id_zamowienia ,1 ,1) = 'W ' then ' WEST ' when substr ( id_zamowienia ,1 ,1) = 'C ' then ' CENTER ' end ) , CONSTRAINT klient_zam_range_hash_fk FOREIGN KEY ( id_klienta ) REFERENCES klienci_hash ( id_klienta )) PARTITION BY RANGE ( data_zam ) SUBPARTITION BY HASH ( id_klienta ) SUBPARTITIONS 8 ( PARTITION zam_sty14 VALUES LESS THAN ( TO_DATE ( '1 -02 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_lut14 VALUES LESS THAN ( TO_DATE ( '1 -03 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_marz14 VALUES LESS THAN ( TO_DATE ( '1 -04 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_kwie14 VALUES LESS THAN ( TO_DATE ( '1 -05 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_maj14 VALUES LESS THAN ( TO_DATE ( '1 -06 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_czer14 VALUES LESS THAN ( TO_DATE ( '1 -07 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_lip14 VALUES LESS THAN ( TO_DATE ( '1 -08 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_sier14 VALUES LESS THAN ( TO_DATE ( '1 -09 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_wrze14 VALUES LESS THAN ( TO_DATE ( '1 -10 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_paz14 VALUES LESS THAN ( TO_DATE ( '1 -11 -2014 ' , 'DD - MM - YYYY ')) , PARTITION zam_lis14 VALUES LESS THAN ( TO_DATE ( '1 -12 -2014 ' , 'DD - MM - YYYY ')) , 51

PARTITION zam_gru14 VALUES LESS THAN ( TO_DATE ( '1 -01 -2015 ' , 'DD - MM - YYYY '))) TABLESPACE ZAM_TB PARALLEL ; alter table zam_range_hash add constraint \ textit { zam_range_hash_pk } primary key ( id_zamowienia ) using index global TABLESPACE IND_ZAM ;

Listing

48:

Polecenia

tworz¡ce

partycjonowane

lokalnie

indeksy

tabeli

zam_range_hash.

CREATE INDEX zam_range_hash_fk ON zam_range_hash ( id_klienta ) LOCAL TABLESPACE IND_ZAM NOLOGGING ; CREATE BITMAP INDEX zam_range_hash_bitmap ON zam_range_hash ( region ) LOCAL PARALLEL TABLESPACE IND_ZAM NOLOGGING ;

Listing 49: Rozkªad danych mi¦dzy partycje tabeli zam_range_hash z uwzgl¦dnieniem ilo±ci subpartycji przypadaj¡cych na ka»d¡ z partycji (dla 60 mln wierszy).

SQL > SELECT partition_name , num_rows , subpartition_count , high_value FROM dba_tab_partitions WHERE table_name = ' ZAM_RANGE_HASH '; PARTITION_NAME NUM_ROWS

SUBPARTITION_COUNT HIGH_VALUE

-------------- ---------- ------------------ --------------------------ZAM_STY14

5080479

8 TO_DATE ( ' 2014 -02 -01 00:00:00 '

ZAM_LUT14

4589110

8 TO_DATE ( ' 2014 -03 -01 00:00:00 '

ZAM_MARZ14

5081875

8 TO_DATE ( ' 2014 -04 -01 00:00:00 '

ZAM_KWIE14

4921914

8 TO_DATE ( ' 2014 -05 -01 00:00:00 '

ZAM_MAJ14

5079152

8 TO_DATE ( ' 2014 -06 -01 00:00:00 '

ZAM_CZER14

4923316

8 TO_DATE ( ' 2014 -07 -01 00:00:00 '

ZAM_LIP14

5080357

8 TO_DATE ( ' 2014 -08 -01 00:00:00 '

ZAM_SIER14

5081236

8 TO_DATE ( ' 2014 -09 -01 00:00:00 '

ZAM_WRZE14

4916023

8 TO_DATE ( ' 2014 -10 -01 00:00:00 '

ZAM_PAZ14

5083158

8 TO_DATE ( ' 2014 -11 -01 00:00:00 '

ZAM_LIS14

4916954

8 TO_DATE ( ' 2014 -12 -01 00:00:00 '

ZAM_GRU14

5082742

8 TO_DATE ( ' 2015 -01 -01 00:00:00 '

52

Listing 50: Indeks lokalny tabeli zam_range_hash partycjonowany dwupoziomowo.

SQL > SELECT partition_name , num_rows , composite FROM dba_ind_partitions WHERE index_name = ' ZAM_RANGE_HASH_FK '; PARTITION_NAME

NUM_ROWS

COM

--------------- ---------- --ZAM_STY14

5466078

YES

ZAM_LUT14

4678640

YES

ZAM_MARZ14

5042471

YES

ZAM_KWIE14

4797830

YES

ZAM_MAJ14

5153882

YES

ZAM_CZER14

4884805

YES

ZAM_LIP14

5180683

YES

ZAM_SIER14

4970592

YES

ZAM_WRZE14

4866715

YES

ZAM_PAZ14

5056396

YES

ZAM_LIS14

4855964

YES

ZAM_GRU14

5009948

YES

3.4 Generacja danych testowych Na potrzeby generacji danych testowych powstaªy dwa skrypty zam_c.sql i

klienci_c.sql napisne w j¦zyku PL/SQL. Pierwszy z nich dotyczy tabeli zamowienia lub jej pochodnych tabel partycjonowanych - zamowienia_hash, zamowienia_ref,

zamowienia_inter, zamowienia_list, zam_range_hash, zam_inter_list, drugi za± tabeli klienci lub jej pochodnych tabel partycjonowanych - klienci_hash, klienci_ref. Sposób generowania wierszy oraz nast¦pnego ich wstawiania do tabeli jest identyczny bez znaczenia na to czy tabela jest partycjonowana i w jaki sposób. Ka»dy ze skryptów skªada si¦ z dwóch logicznych cz¦±ci: pseudolosowego generowania warto±ci poszczególnych pól rekordu oraz nast¦puj¡cego po tym wstawieniu go do wybranej tabeli. Te dziaªania s¡ przeprowadzane w p¦tli, która wykonuje si¦ tyle razy ile chcemy wstawi¢ wierszy do tabeli. Dane generowane s¡ pseudolosowo przy u»yciu funkcji pakietu DBMS_RANDOM, który przy ka»dym wywoªaniu skryptu byª inicjowany t¡ sam¡ warto±ci¡ ziarna:

dbms_random . initialize (681457802);

53

To gwarantuje, »e skrypt przy ka»dym wywoªaniu wstawi takie same rekordy danych do tabeli (zakªadaj¡c brak ingerencji w parametry). Korzystaªam z tej wªa±ciwo±ci, aby móc wypeªnia¢ kolejne partycjonowane tabele w dogodnym momencie, a nie by¢ zmuszon¡ wstawia¢ do nich danych w tym samym momencie.

3.4.1

Generacja danych tabeli klienci

Tabele klienci, klienci_ref oraz klienci_hash byªy wypeªniane danymi w trzech turach. W pierwszej wstawiono do ka»dej z tabel 30 mln rekordów - id_klienta od 1 do 30000000 (licznik p¦tli FOR, linia nr 10), a w drugiej wstawiono drugie tyle wierszy - id_klienta od 30000001 do 60000000. Nast¦pnie zdecydowano si¦ przeprowadzi¢ testy równie» na po±redniej wielko±ci tabel - 45 mln rekordów. Oznacza to, »e tabele te byªy testowane w trzech rozmiarach przy 30, 45 i 60 mln wierszy. Pole id_klienta byªo w ka»dym obiegu p¦tli FOR ustawiana jako aktualna warto±¢ jej licznika. Aby zapewni¢, »e wstawiane do tabeli dane ka»dego z klientów b¦d¡ zawieraªy kolumn¦ miasto z warto±ci¡ nale»¡c¡ do listy 21 nazw miast, na podstawie której potem byªo dokonywane partycjonowanie listowe na tabeli klienci_ref, stworzono pomocnicz¡ tabel¦ miasta. W skrypcie na podstawie warto±ci kolumny

miasta.id i aktualnej warto±ci licznika p¦tli FOR dokonywano przyporz¡dkowania miasta do klienta (linia nr 12).

Listing 51: Polecenie tworz¡ce pomocnicz¡ tabel¦ miasta.

create table miasta ( id NUMBER (2) , nazwa VARCHAR2 (20) , constraint miasta_PK primary key ( id )); Kolumny nazwisko, imie, kod i adres byªy generowane bez dodatkowych zale»no±ci, poniewa» ich warto±ci nie miaªy znaczenia w odniesieniu do zastosowanych metod partycjonowania czy zapyta«, które byªy wykonywane na tabelach w czasie testów.

54

Listing 52: Skrypt klienci_c.sql generuj¡cy i wstawiaj¡cy 30 mln rekordów danych do tabeli klienci. 1

DECLARE

2

naz VARCHAR2 (25);

3

im

4

mias VARCHAR2 (20);

5

k NUMBER (6);

6

ad VARCHAR2 (30);

7

n NUMBER (2);

8

VARCHAR2 (15);

BEGIN dbms_random . initialize (681457802);

9 10

FOR i IN 1..30000000

11

LOOP

12

n := MOD (i , 21) + 1;

13

SELECT m . nazwa INTO mias FROM miasta m WHERE m . id = n ;

14

naz := dbms_random . string ( 'L ' , 25);

15

im := dbms_random . string ( 'L ' , 15);

16

k := TRUNC ( dbms_random . value (10000 , 99999));

17

ad := ( dbms_random . string ( 'L ' , 20)|| ' ' || TRUNC ( dbms_random . value (1 , 200)));

18

INSERT INTO klienci

19

( id_klienta , nazwisko , imie , miasto , kod , adres )

20

VALUES

21

(i , naz , im , mias , k , ad );

22

END LOOP ;

23

dbms_random . terminate ;

24

COMMIT ;

25

END ;

26

/

-- wybor miasta

55

3.4.2

Generacja danych tabeli zamownienia

Tabele zamownienia, zamowienia_ref, zamowienia_hash, zamowienia_list, za-

mowienia_inter, zamowienia_inter_list, zamowienia_range_hash byªy wypeªniane danymi rówenie» w dwóch turach. W pierwszej wstawiono do ka»dej z tabel 60 mln rekordów - id_zamowienia od 1 do 60000000 (licznik p¦tli FOR, linia nr 10), a w drugiej wstawiono drugie tyle wierszy - id_zamowienia od 60000001 do 120000000. Nast¦pnie zdecydowano si¦ przeprowadzi¢ testy równie» na po±redniej wielko±ci tabel - 90 mln rekordów. Oznacza to, »e tabele te byªy testowane w trzech rozmiarach przy 60, 90 i 120 mln wierszy. Pole id_zamowienia (na podstawie którego jest tworzona kolumna wirtualna

zamowienia.region ) skªada si¦ z dwóch cz¦±ci oddzielonych znakiem '_'. Pierwsza cz¦±¢ jest jedn¡ z 5 mo»liwych liter 'CNSWE', a druga to liczba ustawiana na podstawie aktualnej warto±ci licznika p¦tli FOR (linia nr 12). Data zamowienia - kolumna zamowienia.data_zam przyjmuje pseudolosow¡ warto±¢ z zakresu roku 2014 (linia nr 14). Jest ona kluczem partycjonowania dla tabel: zamowienia_inter,

zamowienia_inter_list, zamowienia_range_hash. Warto±¢ klucza obcego zamowienia.id_klienta jest pseudolosowo przyporz¡dkowywana na podstawie wiedzy ile wierszy danych zawiera odpowiednio tabela klienci, klienci_hash lub klienci_ref (linia nr 16). Pole zamowienia.kwota jest generowane bez dodatkowych zale»no±ci, poniewa» jego warto±¢ nie miaªa znaczenia w odniesieniu do zastosowanych metod partycjonowania czy zapyta«, które byªy wykonywane na tabelach w czasie testów. Listing 53: Skrypt zam_c.sql generuj¡cy i wstawiaj¡cy 60 mln rekordów danych do tabeli zamowienia. 1

DECLARE

2

id_zam VARCHAR2 (25);

3

kw NUMBER (6 ,2);

4

d DATE ;

5

id_kl NUMBER (15);

6

n NUMBER (15);

7

-- liczba wierszy tabeli klienci

BEGIN

8

dbms_random . initialize (681457802);

9

SELECT COUNT (*) INTO n FROM klienci ;

10

FOR i IN 1..60000000

11

LOOP 56

12

id_zam :=( SUBSTR ( ' CNSWE ' , TRUNC ( dbms_random . value (1 ,6)) ,1)|| '_ ' || TO_CHAR ( i ));

13

-- losowa data z roku 2014

14

d := TO_DATE ( ' 01 -01 -2014 ' , 'dd - mm - yyyy ') + TRUNC ( DBMS_RANDOM . value (0 ,366));

15

kw := round ( dbms_random . value (5.01 , 9999.98) ,2);

16

id_kl := TRUNC ( dbms_random . value (1 , n +1)); -- losowy klient

17

INSERT INTO zamowienia

18

( id_zamowienia , data_zam , kwota , id_klienta )

19

VALUES

20

( id_zam , d , kw , id_kl );

21

END LOOP ;

22

dbms_random . terminate ;

23

COMMIT ;

24

END ;

25

/

3.5 Aplikacja testowa Aplikacja testowa zostaªa napisana w j¦zyku Java przy u»yciu sterowników JDBC Oracle przeznaczonych do bazy Oracle 11gR2 (archiwum ojdbc6.jar) umo»liwiaj¡cych nawi¡zanie zdalnego poª¡czenia z bazami danych z maszyn orem1 lub orem2. Po nawi¡zaniu poª¡czenia z wybran¡ z baz danych aplikacja wysyªa do niej kolejno zapytania SQL typu SELECT i mierzy czas odpowiedzi na rezultaty ka»dego z nich. Dokªadniejsze informacje zostaªy zawarte w dwóch nast¦pnych podrozdziaªach. Kod ¹ródªowy aplikacji jest przedstawiony w Zaª¡czniku A - kod ¹ródªowy

aplikacji testowej.

3.5.1

Budowa i dziaªanie aplikacji

Aplikacja oparta jest na klasie Polaczenie, która zawiera trzy metody:



public void polaczenie_z_baza() - jej gªówn¡ funkcjonalno±ci¡ jest zaªadowanie odpowiednich sterowników oraz nawi¡zanie poª¡czenia z wybran¡ baz¡ danych (linie 35- 34). Nast¦pnie ustawiane s¡ dodatkowe parametry dotycz¡ce wykonywania zapyta«. Pierwszy z nich sprawia (linia nr 62), »e lista wysyªanych zapyta« b¦dzie traktowana jako jedna transakcja, zatwierdzanie nast¦puje po zako«czonym sukcesem wykonaniu zapyta« testowych. Dwie kolejne (linie 64,

57

65) wywoªuj¡ polecenia DDL maj¡ce na celu wyczyszczenie buforów bazy danych ALTER SYSTEM FLUSH BUFFER_CACHE oraz obszaru dzielonego

ALTER SYSTEM FLUSH SHARED_POOL. Uznaªam, »e usuni¦cie wyników oraz planów wykona« poprzednich zapyta« jest rozs¡dne w przypadku powtarzania testów skªadaj¡cych si¦ z tych samych zapyta«, bo pomoga w zachowaniu ich niezale»no±ci. Chciaªam uzyska¢ jak najbardziej warto±ciowe wyniki bada«. Nast¦pnie dla ka»dego z zapyta« testowych wywoªywana jest metoda

test. Na koniec zwalniane s¡ wszystkie zasoby oraz zamykane jest poª¡czenie z baz¡ danych. W przypadku przechwycenia wyj¡tku w konsoli wy±wietlana jest tre±¢ bª¦du. Ponadto w przypadku bª¦dów dotycz¡cych wykonania polece« SQL dokonywane jest zwolnienie zaj¦tych zasobów, przywracany jest stan bazy danych sprzed rozpocz¦cia transakcji (polecenie ROLLBACK ) oraz zamykane jest poª¡czenie.



private void test(Statement stm, String query, PrintWriter zapis)

- metoda

wywoªywana dla ka»dego z zapyta« testowych. Wykonuje zapytanie, które dostaje w argumencie String query i mierzy okres czasu (w milisekundach) jaki upªyn¡ª od momentu wysªania zapytania do bazy danych i otrzymania jego wyników. Listing 54: Sposób mierzenia czasu wykonania zapytania, fragment aplikacji testowej.

long start = System . currentTimeMillis (); ResultSet res = stm . executeQuery ( query ); long time = System . currentTimeMillis () - start ; Tre±¢ zapytania oraz tak obliczany czas jego wykonania s¡ nast¦pnie wypisywane na konsol¦ oraz zapisywane do pliku dane.txt.



public static void main(String[] args) - tworzy nowy obiekt klasy Polaczenie i wywoluje jego metod¦ polaczenie_z_baza().

3.5.2

Zapytania testowe

W testach korzystam z 7 zapyta«. Ka»de z nich zostaªo tak skonstruowane, aby umo»liwiaªo skorzystnie z ewentualnych dodatkowych mechanizmów dotycz¡cych partycjonowania (przycinanie partycji, zª¡czenia partycji), które w teorii maj¡ skró-

58

ci¢ czas jego wykonywania w stosunku do tabeli niepartycjonowanej. Z tego wzgl¦du klauzule WHERE zawieraj¡ warunki selekcji oparte na kluczach partycjonowania. Pod Listingiem 48 dokonane jest obja±nienie jak przedstawione w nim zapytania byªy wykorzystywane w testach. Listing 55: Zapytania testowe na przykªadzie niepartycjonowanych tabel zamowienia oraz klienci (fragment kodu aplikacji testowej)

String query1 = " SELECT COUNT (*) FROM klienci WHERE miasto = ' KATOWICE ' " ; String query2 = " SELECT COUNT (*) FROM zamowienia WHERE region = ' WEST ' " ; String query3 = " SELECT SUM ( kwota ) FROM zamowienia " + " WHERE data_zam BETWEEN ( TO_DATE ( '01 -06 -2014 ' , 'DD - MM - YYYY ')) " + " AND ( TO_DATE ( '01 -07 -2014 ' , 'DD - MM - YYYY ')) " ; String query4 = " SELECT sum ( kwota ) FROM zamowienia " + " WHERE id_klienta = 123456 AND " + " z . data_zam BETWEEN ( TO_DATE ( '01 -02 -2014 ' , 'DD - MM - YYYY ')) " + " AND ( TO_DATE ( '01 -03 -2014 ' , 'DD - MM - YYYY ')) " ; String query5 = " SELECT AVG ( kwota ) FROM zamowienia

" +

" WHERE data_zam BETWEEN ( TO_DATE ( '01 -02 -2014 ' , 'DD - MM - YYYY ')) " + " AND ( TO_DATE ( '01 -05 -2014 ' , 'DD - MM - YYYY ')) AND region = ' CENTER ' " ; String query6 = " SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien " + " FROM zamowienia z , klienci k

WHERE z . id_klienta = k . id_klienta AND " +

" z . data_zam BETWEEN ( TO_DATE ( '01 -06 -2014 ' , 'DD - MM - YYYY ')) " + " AND ( TO_DATE ( '01 -07 -2014 ' , 'DD - MM - YYYY ')) GROUP BY k . nazwisko " ; String query7 = " COUNT (*) liczba_zamowien " + " FROM zamowienia z , klienci k WHERE z . id_klienta = k . id_klienta AND " + " k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ') " ;



query1 - zapytanie zwraca liczb¦ klientów mieszkaj¡cych w Katowicach. Byªo wykonanywane na tabeli klienci oraz jej pochodnych tabelach partycjonowanych - klienci_ref i klienci_hash ;



query2 - zapytanie zwraca liczb¦ zamówie« zªo»onych w regionie WEST . Byªo wykonywane na tabeli zamowienia oraz na jej pochodnych tabelach partycjonowanych - zamowienia_ref, zamowienia_hash, zamowienia_inter, za-

mowienia_list, zam_inter_list i zam_range_hash ;



query3 - zapytanie zwraca sum¦ warto±ci zamówie« z okresu jednego miesi¡ca. Byªo wykonywane na tabeli zamowienia oraz na jej pochodnych tabelach par-

59

tycjonowanych - zamowienia_ref, zamowienia_hash, zamowienia_inter, za-

mowienia_list, zam_inter_list i zam_range_hash ;



query4 - zapytanie zwraca sum¦ warto±ci zamówie« dla wybranego klienta z okresu jednego miesi¡ca. Byªo wykonywane na tabeli zamowienia oraz na jej pochodnych tabelach partycjonowanych - zamowienia_ref, zamowienia_hash,

zamowienia_inter, zamowienia_list, zam_inter_list i zam_range_hash ;



query5 - zapytanie zwraca ±redni¡ sum¦ warto±ci zamowie« z okresu trzech miesi¦cy w regionie CENTER .



query6, query7 - zapytania wymagaj¡ce zª¡cze« mi¦dzy tabelami typu zamowienia oraz klienci. Nast¦puj¡ce konguracje zª¡cze« zostaªy uwzgl¦dnione w testach:



tabela klienci byªa zª¡czana z tabel¡ zamowienia,



tabela klienci_ref byªa zª¡czana z tabel¡ zamowienia_ref,



tabela klienci_hash byªa zª¡czana z pozostaªymi tabelami partycjonowanymi czyli z zamowienia_hash, zamowienia_inter, zamowienia_list,

zam_inter_list i zam_range_hash. Zapytanie query6 zwraca sum¦ warto±ci zamowie« dla ka»dego z klientów z okresu jednego miesi¡ca, za± query7 podaje liczb¦ zamówie« zªo»onych przez klientów mieszkaj¡cych w Warszawie, Biaªymstoku, Lublinie lub Radomiu.

60

4

Testy Tak jak ju» zostaªo wspomniane w poprzednim rozdziale, testy byªy przepro-

wadzane na trzch rozmiarach danych. Dla tabel typu klienci byªo to 30, 45 i 60 milionów wierszy, za± tabele typu zamowienia byªy testowane dla 60, 90 i 120 milionów wierszy. Zª¡czenia mi¦dzy tabelami odbywaªy si¦ w trzech konguracjach rozmiarowych: mi¦dzy tabelami typu klienci o 30 mln rekordów i zamowienia o 60 mln, dla tabel typu klienci o 45 mln rekordów i zamowienia o 90 mln oraz trzecia dla tabel typu klienci o 60 mln rekordów i zamowienia o 120 mln rekordów. Ka»dy z pomiarów czasu (w milisekunach) wykonania ka»dego z zapyta« dla danej tabeli o wybranej konguracji indeksowej byª przeprowadzany trzykrotnie. Rozrzut mi¦dzy warto±ciami otrzymanych wyników pomiarów wynosiª ok. 30%. Aby zachowa¢ przejrzysto±¢ w pracy znajduj¡ si¦ u±rednione warto±ci tych trzech wyników (tabele w nast¦pnych podrozdziaªach). Przed wykonaniem testów dla nowej konguracji partycji tabeli i indeksów, gromadzone byªy statystyki. Po wykonaniu skryptu zam_c.sql lub kllienci_c.sql w celu zwi¦kszenia rozmiarów tabel ich indeksy byªy przebudowywane. Listing 56: Przykªad zbierania statystyk dla tabeli zamowienia_ref oraz jej indeksów.

exec dbms_stats . gather_table_stats ( ' SYS ' , ' ZAMOWIENIA_REF ' , GRANULARITY = > ' ALL ' ); exec dbms_stats . gather_index_stats ( ' SYS ' , ' ZAM_REF_FK ' , GRANULARITY = > ' ALL ' ); exec dbms_stats . gather_index_stats ( ' SYS ' , ' ZAM_REF_BITMAT , GRANULARITY = > ' ALL ' ); exec dbms_stats . gather_index_stats ( ' SYS ' , ' ZAM_REF_PK ' ); W nast¦pnych podrozdziaªach zostan¡ przedstawione wyniki bada« efektywno±ci poszczególnych metod partycjonowania tabel oraz indeksów w odniesieniu do przygotowanej listy zapyta« testowych.

61

4.1 Tabele klienci,

klienci_ref

oraz

klienci_hash

Wyniki testów (wykonanych przez aplikacj¦ testow¡) na niepartycjonowanej tabeli klienci, partycjonowanej listowo wg kolumny miasto tabeli klienci_ref

oraz

partycjonowanej metod¡ mieszaj¡c¡ opart¡ na kluczu gªównym id_klienta tabeli

klienci_hash zostaªy przedstawione w Tablicy 2 oraz Tablicy 3. Dokªadny opis tabel zostaª zamieszczony we wcze±niejszej cz¦±ci pracy, w rozdziale 3.3 Relacyjny model

danych - dla tabeli klienci, podrozdziale 3.3.1 Partycjonowanie referencyjne - dla tabeli klienci_ref oraz 3.3.2 Partycjonowanie mieszaj¡ce - dla tabeli klienci_hash. Mierzono czas wykonania nast¦puj¡cego zapytania (odpowiednio dla ka»dej z tabel):

SELECT COUNT (*) FROM klienci WHERE miasto = ' KATOWICE '; SELECT COUNT (*) FROM klienci_ref WHERE miasto = ' KATOWICE '; SELECT COUNT (*) FROM klienci_hash WHERE miasto = ' KATOWICE '; Zapytanie zwraca liczb¦ klientów mieszkaj¡cych w Katowicach.

Tablica 2: Czas wykonania zapytania testowego (w ms) dla tabel klienci, klienci_ref oraz klienci_hash dla dwóch rozmiarów tabel (w mln wierszy)

rozmiar tabel

tabela

tabela

tabela

klienci [ms]

klienci_ref [ms]

klienci_hash [ms]

30

33630

19354

28239

45

163000

29547

153625

60

229880

38235

176422

Wyniki testów s¡ zgodne dla wszystkich rozmiarów tabel. Najdªu»ej zapytanie byªo wykonywane na niepartycjonowanej tabeli klienci, najkrócej za± na tabeli

klienci_ref. Przyczyn¡ takich rezultatów jest fakt, i» klauzula WHERE zapytania zawiera warunek równo±ci oparty na kluczu partycjonowania tabeli klienci_ref

i

zostaªo przeprowadzone przycinanie partycji (dost¦p byª jedynie do parycji nr 5). W przypadku tabeli klienci_hash pozytywny wpªyw na czas wykonania mogªa mie¢ mo»liwo±¢ równolegªego skanowania partycji.

62

Rysunek 12: Plan wykonania zapytania dla tabeli klienci_ref

o 30 mln wierszy,

potwierdzaj¡cy u»ycie mechanizmu przycinania partycji.

Rysunek 13: Plan wykonania zapytania dla tabeli klienci_hash o 30 mln wierszy, obrazuj¡cy przeprowadzenie zapytania równolegªego.

63

4.2 Tabela zamowienia Wyniki testów (wykonanych przez aplikacj¦ testow¡) na niepartycjonowanej tabeli zamowienia zostaªy przedstawione w Tablicy 3, Tablicy 4 oraz Tablicy 5. Kolumny tych tablic wskazuj¡ sposób indeksowania tabeli zamowienia w danym przypadku testowym. Kolejno nazwy tych kolumn oznaczaj¡:



bez indeksów - zaªo»ony jest tylko niepartycjonowany indeks na klyczu gªównym id_zamowienia ;



niepartycjonowane - zaªo»one s¡ niepartycjonowane indeksy na kluczu gªównym, kluczu obcym id_klienta oraz bitmapowy na kolumnie region ;



globalny - zaªo»one s¡ niepartycjonowane indeksy na kluczu gªównym i na kolumnie region, indeks na kluczu obcym jest partycjonowany globalnie metod¡ zakresow¡.

Dokªadny opis tabeli zamowienia zostaª zamieszczony we wcze±niejszej cz¦±ci pracy, w rozdziale 3.3 Relacyjny model danych. Mierzono czas wykonania nast¦puj¡cych zapyta«:

1. Zapytanie zwraca liczb ¦ zam ó wie « z ª o » onych w regionie " WEST " . SELECT COUNT (*) FROM zam_inter_list WHERE region = ' WEST '; 2. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « z okresu jednego miesi ¡ ca . SELECT SUM ( kwota ) FROM zamowienia WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )); 3. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « dla wybranego klienta z okresu jednego miesi ¡ ca . SELECT sum ( kwota ) FROM zamowienia WHERE id_klienta = 123456 AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -03 -2014 ' , 'DD - MM - YYYY ' )); 4. Zapytanie zwraca ± redni ¡ sum ¦ warto ± ci zamowie « z okresu trzech miesi ¦ cy w regionie " CENTER " . SELECT AVG ( kwota ) FROM zamowienia WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -05 -2014 ' , 'DD - MM - YYYY ' )) AND region = ' CENTER '; 5. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia oraz klienci , zwraca sum ¦ warto ± ci zamowie « dla ka » dego z klient ó w z okresu jednego miesi ¡ ca . 64

SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien FROM zamowienia z , klienci k WHERE z . id_klienta = k . id_klienta AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )) GROUP BY k . nazwisko ; 6. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia oraz klienci , podaje liczb ¦ zam ó wie « z ª o » onych przez klient ó w mieszkaj ¡ cych w Warszawie , Bia ª ymstoku , Lublinie lub Radomiu . SELECT COUNT (*) liczba_zamowien FROM zamowienia z , klienci k WHERE z . id_klienta = k . id_klienta AND k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ' );

Tablica 3: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia o 60 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez indeksów [ms]

niepartycjonowane [ms] globalny [ms]

1

77890

2209

2568

2

2078

34189

3568

3

2101

16

5

4

2223

2235

2245

5

2045

2076

2105

6

179703

116709

187568

Tablica 4: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia o 90 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez indeksów [ms]

niepartycjonowane [ms] globalny [ms]

1

111453

3569

2157

2

172734

91484

78828

3

33391

38

101

4

113453

56406

54906

5

4943

42094

54954

6

242563

181656

288125

65

Tablica 5: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia o 120 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez indeksów [ms]

niepartycjonowane [ms] globalny [ms]

1

123912

1791

2073

2

213198

165721

160812

3

41897

6

73

4

12152

98025

169508

5

5484

48022

78666

6

494288

312926

534343

Wyniki przeprowadzonych testów wskazuj¡ no to, »e zastosowanie indeksu globalnie partycjonowanego na kluczu obcym id_klienta tabeli zamowienia przyniosªo korzy±ci dla rozmiarów tabeli 90 i 120 mln dla zapytania nr 2, chocia» nie zostaª przy jego wykonaniu wykarzystany »aden z mechanizmów dotycz¡cych partycjonowania poprawiaj¡cych efektywno±¢. Dla rozmiaru tabeli równego 30 mln wierszy i zapytania nr 3, osi¡gni¦to wynik 3 razy lepszy ni» w przypadku zastosowania indeksów niepartycjonowanych. Zostaª osi¡gni¦ty lepszy wynik dla partycjonowanego indeksu, gdy» miaªo miejsce statyczne przycinanie partycji. Przeszukiwana jest tylko jedna z 8 partycji indeksu, ta w której znajduj¡ si¦ dane klienta o id_klienta równym 12345. Zapytanie nr 1 zostaªo szybciej wykonane przy u»yciu indeksu partycjonowanego przy rozmiarze tabeli równym 90 mln. Indeks partycjonowany nie sprawdziª si¦ jednak w odniesieniu do ostatnich trzech zapyta«. Warto zwróci¢ uwag¦ na fakt, i» w niektórych przypadkach globalny indeks partycjonowany spowodowaª wydªu»enie czasu oczekiwania na rezultaty zapytania nawet w porównaniu z tabel¡ bez indeksu na kluczu obcym. Zaobserwowa¢ mo»na równie» ciekawy przypadek dla tabeli zamo-

wienia z niepartycjonowanymi indeksami, zapytanie nr 3 wykonane zostaªo szybciej dla wi¦kszego rozmiaru tabeli.

66

Rysunek 14: Plan wykonania zapytania nr 6 dla tabeli zamowienia o 60 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu zrównoleglenia i wykorzystania indeksu globalnie partycjonowanego na kluczu obcym.

Rysunek 15: Plan wykonania zapytania nr 3 dla tabeli zamowienia o 30 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu przycinania partycji. Przeszukiwana byªa tylko pierwsza partycja indeksu globalnie partycjonowanego na kluczu obcym id_klienta.

67

4.3 Tabela zamowienia_ref Wyniki testów (wykonanych przez aplikacj¦ testow¡) na tabeli zamowienia_ref partcjonowanej referencyjnie wg wzoru tabeli klienci_ref zostaªy przedstawione w Tablicy 6, Tablicy 7 oraz Tablicy 8. Kolumny tych tablic wskazuj¡ sposób indeksowania tabeli zamowienia_ref w danym przypadku testowym. Kolejno nazwy tych kolumn oznaczaj¡:



bez indeksów - tylko globalny niepartycjonowany indeks na kluczu gªównym

id_zamowienia ;



z lokalnymi - z globalnym niepartycjonowanym indeksem na kluczu gªównym, z partycjonowanymi lokalnie indeksami bitmapowym na kolumnie region oraz drzewiastym na kluczu obcym id_klienta ;

Dokªadny opis tabeli zamowienia_ref zostaª zamieszczony we wcze±niejszej cz¦±ci pracy, w podrozdziale 3.3.1 Partycjonowanie referencyjne. Mierzono czas wykonania nast¦puj¡cych zapyta«:

1. Zapytanie zwraca liczb ¦ zam ó wie « z ª o » onych w regionie " WEST " . SELECT COUNT (*) FROM zamowienia_ref WHERE region = ' WEST '; 2. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « z okresu jednego miesi ¡ ca . SELECT SUM ( kwota ) FROM zamowienia_ref WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )); 3. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « dla wybranego klienta z okresu jednego miesi ¡ ca . SELECT sum ( kwota ) FROM zamowienia_ref WHERE id_klienta = 123456 AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -03 -2014 ' , 'DD - MM - YYYY ' )); 4. Zapytanie zwraca ± redni ¡ sum ¦ warto ± ci zamowie « z okresu trzech miesi ¦ cy w regionie " CENTER " . SELECT AVG ( kwota ) FROM zamowienia_ref WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -05 -2014 ' , 'DD - MM - YYYY ' )) AND region = ' CENTER '; 5. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia_ref oraz klienci_ref , zwraca sum ¦ warto ± ci zamowie « dla ka » dego z klient ó w z okresu jednego miesi ¡ ca . SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien 68

FROM zamowienia_ref z , klienci_ref k WHERE z . id_klienta = k . id_klienta AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )) GROUP BY k . nazwisko ; 6. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia_ref oraz klienci_ref , podaje liczb ¦ zam ó wie « z ª o » onych przez klient ó w mieszkaj ¡ cych w Warszawie , Bia ª ymstoku , Lublinie lub Radomiu . SELECT COUNT (*) liczba_zamowien FROM zamowienia_ref z , klienci_ref k WHERE z . id_klienta = k . id_klienta AND k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ' );

Tablica 6: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia_ref o 60 mln wierszy i dwóch konguracjach indeksowych.

nr zapytania

bez indeksów [ms]

z lokalnymi [ms]

1

12370

249

2

1452

9969

3

344

78

4

1527

1654

5

16562

8328

6

58677

63708

Tablica 7: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia_ref o 90 mln wierszy dwóch konguracjach indeksowych.

nr zapytania

bez indeksów [ms]

z lokalnymi [ms]

1

10657

1005

2

51765

47683

3

876

156

4

3563

3891

5

51975

49611

6

96583

78239

69

Tablica 8: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia_ref o 120 mln wierszy dwóch konguracjach indeksowych.

nr zapytania

bez indeksów [ms]

z lokalnymi [ms]

1

108395

1552

2

69221

65143

3

1180

250

4

48226

49811

5

70315

72133

6

195967

135730

W przypadku zapytania nr 1 dla wszystkich rozmiarów tabela zamowienia_ref z lokalnymi indeksami otrzymaªa lepsze wyniki ni» niepartycjonowana tabela za-

mowienia. Dla rozmiarów tabel równych 90 i 120 mln wierszy oraz zapytania nr 2 partycjonowanie referencyjnie tabeli zamowienia równie» okazaªo si¦ przynosi¢ lepsze rezultaty. Za± dla rozmiarów równych 60 i 90 mln wierszy szybciej wykonaªo si¦ w obu konguracjach indeksowych zapytanie nr 4. Najlepszy jednak wynik, bo nawet trzykrotne przy±pieszenie wykonania nast¡piªo dla obu rozmiarów i modeli indeksów w odniesiu do ostatniego zapytania. Mamy tu doczynienia z równolegªym wykonaniu zª¡cze« na poziomie partycji oraz przycinaniem partycji, poniewa» tabele

zamowienia_ref i klienci_ref s¡ partycjonowane referencyjnie (zª¡czenia na poziomie partycji) listowo na kolumnie miasto, która znajduje si¦ w klauzuli WHERE przy predykacie IN warunku zawierania (przycinanie partycji). Wyst¦puje tu jednak tzw. dynamiczne przycinanie partycji, mniej efektywne ni» statyczne, ale ci¡gle korzystne. Wskazuje na to sªowo kluczowe KEY w kolumnach Pstart i Pstop w zaprezentowanym poni»ej planie wykonania.

70

Rysunek 16: Plan wykonania zapytania nr 6 dla tabeli zamowienia_ref o 60 mln wierszy, wskazuj¡cy na równolegle wykonywane zª¡cze« na poziomie partycji oraz dynamiczne przycinanie partycji.

4.4 Tabela zamowienia_hash Wyniki testów (wykonanych przez aplikacj¦ testow¡) na tabeli zamowienia_hash partycjonowanej metod¡ mieszaj¡c¡ na podstawie klucza obcego id_klienta zostaªy przedstawione w Tablicy 9, Tablicy 10 oraz Tablicy 11. Kolumny tych tablic wskazuj¡ sposób indeksowania tabeli zamowienia_hash w danym przypadku testowym. Kolejno nazwy tych kolumn oznaczaj¡:



bez indeksów - tylko globalny niepartycjonowany indeks na kluczu gªównym

id_zamowienia ;



globalny niepartycjonowany - z globalnym niepartycjonowanymi indeksami na kluczu gªównym, obcym id_klienta oraz indeksem bitmapowym na kolumnie

region ;



globalny partycjonowany - z niepartycjonowanymi indeksem na kluczu gªównym, partycjonowanym lokalnie indeksem bitmapowym na kolumnie region oraz globalnym drzewiastym partycjonowanym zakresowo na kluczu obcym

id_klienta.



z lokalnymi - z globalnym niepartycjonowanym indeksem na kluczu gªównym, z partycjonowanymi lokalnie indeksami bitmapowym na kolumnie region oraz

71

drzewiastym na kluczu obcym id_klienta ;

Dokªadny opis tabeli zamowienia_hash zostaª zamieszczony we wcze±niejszej cz¦±ci pracy, w podrozdziale 3.3.2 Partycjonowanie mieszaj¡ce. Mierzono czas wykonania nast¦puj¡cych zapyta«:

1. Zapytanie zwraca liczb ¦ zam ó wie « z ª o » onych w regionie " WEST " . SELECT COUNT (*) FROM zamowienia_hash WHERE region = ' WEST '; 2. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « z okresu jednego miesi ¡ ca . SELECT SUM ( kwota ) FROM zamowienia_hash WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )); 3. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « dla wybranego klienta z okresu jednego miesi ¡ ca . SELECT sum ( kwota ) FROM zamowienia_hash WHERE id_klienta = 123456 AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -03 -2014 ' , 'DD - MM - YYYY ' )); 4. Zapytanie zwraca ± redni ¡ sum ¦ warto ± ci zamowie « z okresu trzech miesi ¦ cy w regionie " CENTER " . SELECT AVG ( kwota ) FROM zamowienia_hash WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -05 -2014 ' , 'DD - MM - YYYY ' )) AND region = ' CENTER '; 5. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia_hash oraz klienci_hash , zwraca sum ¦ warto ± ci zamowie « dla ka » dego z klient ó w z okresu jednego miesi ¡ ca . SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien FROM zamowienia_hash z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )) GROUP BY k . nazwisko ; 6. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia_hash oraz klienci_hash , podaje liczb ¦ zam ó wie « z ª o » onych przez klient ó w mieszkaj ¡ cych w Warszawie , Bia ª ymstoku , Lublinie lub Radomiu . SELECT COUNT (*) liczba_zamowien FROM zamowienia_hash z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ' );

72

Tablica 9: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia_hash o 60 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

29406

1890

4479

2063

2

2624

17359

28677

12005

3

329

302

2187

15

4

1729

3067

63228

1349

5

6260

3187

48781

8609

6

54849

49479

87052

87052

Tablica 10: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia_hash o 90 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

32958

30984

31643

31090

2

18385

19851

15943

19371

3

10762

9041

8310

10137

4

3908

3593

3701

3656

5

168237

165490

170462

154031

6

178264

179026

177292

174841

73

Tablica 11: Czas wykonania zapyta« testowych (w ms) dla tabeli zamowienia_hash o 120 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

45344

46985

35953

46985

2

23656

24625

10594

24625

3

23047

21734

22609

21734

4

5437

4969

4641

4969

5

211829

209969

217234

209969

6

279078

288047

290297

288047

Przy 60 mln rekordów partycjonowanie mieszaj¡ce na bazie klucza obcego okazaªo si¦ opªacalne tylko w stosunku do zapytania nr 2 i 6, jednak nie w przypadku zastosowania globalnego indesu partycjonowanego na kluczu obcym. Zastosowanie tego sposobu partycjonowania indeksu sprawiªo, »e wynik byª znacznie gorszy. W przypadku tabeli zamowienia_hash w drugiej konguracji indeksowej czyli z wszystkimi indeksami niepartycjonowanymi przy zapytaniu nr 6, otrzymano wynik 2 razy lepszy ni» dla tabeli niepartycjonowanej. Równie» zapytanie nr 2 wykonane zostaªo troch¦ szybciej w konguracji z indeksami niepartycjonowanymi i lokalnymi na kluczu obcym oraz kolumnie region. Dla razmiarów 90 i 120 mln wierszy ju» 3 z 7 zapyta« (nr 2, 4, 6) zostaªo wykonanych szybciej ni» przy tabeli niepartycjonowanej. Zapytania te w ka»dej konguracji indeksowej zostaªy wykonane w krótszym czasie ni» na tabeli zamowienia. W przypadku zapyta« nr 2 i 4 jest to znacz¡ca poprawa, bo uzyskano kilkukrotnie lepsze wyniki. Wybór sposobu partycjonowania indeksu jednak nie miaª du»ego wpªywu, poniewa» wyniki te dla ka»dej konguracji s¡ zbli»one. Warty odnotowania jest fakt, »e w przypadku zª¡cze« mi¦dzy tabelami zamowie-

nia_hash i klienci_hash dochodzi do zostosowania mechanizmu wspomagaj¡cego zª¡cze« na poziomie partycji (obie tabele s¡ partycjonowane na kluczu zª¡czenia), które jeszcze dodatkowo mo»e by¢ wykonywane równolegle. Czym wi¦ksza tabela tym bardziej to wpªywa na zwi¦kszenie efektywno±ci przeprowadzania zª¡cze«.

74

Rysunek 17: Plan wykonania zapytania nr 6 dla tabeli zamowienia_hash o 60 mln wierszy, wskazuj¡cy na równolegle wykonywane zª¡cze« na poziomie partycji.

4.5 Tabela zamowienia_list Wyniki testów (wykonanych przez aplikacj¦ testow¡) na tabeli zamowienia_list partycjonowanej listow¡ na podstawie kolumny wirtualnej region zostaªy przedstawione w Tablicy 12, Tablicy 13 oraz Tablicy 14. Kolumny tych tablic wskazuj¡ sposób indeksowania tabeli zamowienia_list w danym przypadku testowym. Kolejno nazwy tych kolumn oznaczaj¡:



bez indeksów - tylko globalny niepartycjonowany indeks na kluczu gªównym

id_zamowienia ;



globalny niepartycjonowany - z globalnym niepartycjonowanymi indeksami na kluczu gªównym, obcym id_klienta.



globalny partycjonowany - z niepartycjonowanymi indeksem na kluczu gªównym, partycjonowanym oraz globalnym drzewiastym partycjonowanym zakresowo na kluczu obcym id_klienta.



z lokalnymi - z globalnym niepartycjonowanym indeksem na kluczu gªównym i z partycjonowanym lokalnie drzewiastym na kluczu obcym id_klienta ;

Dokªadny opis tabeli zamowienia_list zostaª zamieszczony we wcze±niejszej cz¦±ci pracy, w podrozdziale 3.3.3 Partycjonowanie na kolumnie wirtualnej.

75

Mierzono czas wykonania nast¦puj¡cych zapyta«:

1. Zapytanie zwraca liczb ¦ zam ó wie « z ª o » onych w regionie " WEST " . SELECT COUNT (*) FROM zamowienia_list WHERE region = ' WEST '; 2. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « z okresu jednego miesi ¡ ca . SELECT SUM ( kwota ) FROM zamowienia_list WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )); 3. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « dla wybranego klienta z okresu jednego miesi ¡ ca . SELECT sum ( kwota ) FROM zamowienia_list WHERE id_klienta = 123456 AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -03 -2014 ' , 'DD - MM - YYYY ' )); 4. Zapytanie zwraca ± redni ¡ sum ¦ warto ± ci zamowie « z okresu trzech miesi ¦ cy w regionie " CENTER " . SELECT AVG ( kwota ) FROM zamowienia_list WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -05 -2014 ' , 'DD - MM - YYYY ' )) AND region = ' CENTER '; 5. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia_list oraz klienci_hash , zwraca sum ¦ warto ± ci zamowie « dla ka » dego z klient ó w z okresu jednego miesi ¡ ca . SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien FROM zamowienia_list z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )) GROUP BY k . nazwisko ; 6. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia_list oraz klienci_hash , podaje liczb ¦ zam ó wie « z ª o » onych przez klient ó w mieszkaj ¡ cych w Warszawie , Bia ª ymstoku , Lublinie lub Radomiu . SELECT COUNT (*) liczba_zamowien FROM zamowienia_list z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ' );

76

Tablica 12: Czas wykonania zapyta« testowych (mierzony w ms) dla tabeli zamo-

wienia_list o 60 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

567

10614

17380

13036

2

1641

36562

54773

43609

3

1505

140

271

420

4

317

1099

1145

661

5

15755

13740

20203

2859

6

87901

42823

99296

72854

Tablica 13: Czas wykonania zapyta« testowych (mierzony w ms) dla tabeli zamo-

wienia_list o 90 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

15937

17802

17473

16005

2

52086

51737

58719

51843

3

16307

15534

14953

15096

4

4956

12845

12982

5190

5

49625

48153

85635

89375

6

16291

160362

144822

157362

77

Tablica 14: Czas wykonania zapyta« testowych (mierzony w ms) dla tabeli zamo-

wienia_list o 120 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

29145

32062

33412

31947

2

87807

85967

88654

84007

3

27573

19677

29327

37057

4

8599

20854

21345

10454

5

50978

131807

109148

160802

6

246542

286276

175771

213093

Zapytanie nr 1 dla rozmiaru 90 i 120 mln wierszy mimo, »e jest wykonywane dla tabeli zamowienia_list z u»yciem mechanizmu przycinania partycji, to mimo wszystko szybciej zwraca rezultaty dla tabeli zamowienia z indeksem bitmapowym na kolumnie region, która jest kluczem partycjonowania tabeli zamowienia_list. Jednak przy zapytaniu nr 4, które zawiera dwa warunki w klauzuli WHERE bardziej efektywne okazuje si¦ przycinanie partycji poª¡czone ze zrównolegleniem. Jest to szczególnie widoczne dla tabeli zamowienia_list z tylko indeksem na kluczu gªównym i w przypadku tego samego indeksu, ale w poª¡czeniu z lokalnym partycjonowanym na kluczu obcym. Zapytanie nr 6 w ka»dej konguracji indeksowej zostaªo wykonane szybciej ni» w przypadku tabeli zamowienia niepartycjonowanej. Dla tego zapytania równie» zostaªo zastosowane zrówleglenie wykonania zapytania.

78

Rysunek 18: Plan wykonania zapytania nr 4 dla tabeli zamowienia_list o 60 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu zrównoleglenia i przycinania partycji.

4.6 Tabela zamowienia_inter Wyniki testów (wykonanych przez aplikacj¦ testow¡) na tabeli zamowienia_inter partycjonowanej interwaªowo na kolumnie data_zam zostaªy przedstawione w Tablicy 15, Tablicy 16 oraz Tablicy 17. Kolumny tych tablic wskazuj¡ sposób indeksowania tabeli zamowienia_inter w danym przypadku testowym. Kolejno nazwy tych kolumn oznaczaj¡:



bez indeksów - tylko globalny niepartycjonowany indeks na kluczu gªównym

id_zamowienia ;



globalny niepartycjonowany - z globalnym niepartycjonowanymi indeksami na kluczu gªównym, obcym id_klienta oraz indeksem bitmapowym na kolumnie

region ;



globalny partycjonowany - z niepartycjonowanymi indeksem na kluczu gªównym, partycjonowanym lokalnie indeksem bitmapowym na kolumnie region oraz globalnym drzewiastym partycjonowanym metod¡ mieszaj¡c¡ na kluczu obcym id_klienta.



z lokalnymi - z globalnym niepartycjonowanym indeksem na kluczu gªównym, z partycjonowanymi lokalnie indeksami bitmapowym na kolumnie region oraz drzewiastym na kluczu obcym id_klienta ;

79

Dokªadny opis tabeli zamowienia_inter zostaª zamieszczony we wcze±niejszej cz¦±ci pracy, w podrozdziale 3.3.4 Partycjonowanie interwaªowe. Mierzono czas wykonania nast¦puj¡cych zapyta«:

1. Zapytanie zwraca liczb ¦ zam ó wie « z ª o » onych w regionie " WEST " . SELECT COUNT (*) FROM zamowienia_inter WHERE region = ' WEST '; 2. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « z okresu jednego miesi ¡ ca . SELECT SUM ( kwota ) FROM zamowienia_inter WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )); 3. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « dla wybranego klienta z okresu jednego miesi ¡ ca . SELECT sum ( kwota ) FROM zamowienia_inter WHERE id_klienta = 123456 AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -03 -2014 ' , 'DD - MM - YYYY ' )); 4. Zapytanie zwraca ± redni ¡ sum ¦ warto ± ci zamowie « z okresu trzech miesi ¦ cy w regionie " CENTER " . SELECT AVG ( kwota ) FROM zamowienia_inter WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -05 -2014 ' , 'DD - MM - YYYY ' )) AND region = ' CENTER '; 5. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia_inter oraz klienci_hash , zwraca sum ¦ warto ± ci zamowie « dla ka » dego z klient ó w z okresu jednego miesi ¡ ca . SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien FROM zamowienia_inter z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )) GROUP BY k . nazwisko ; 6. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zamowienia_inter oraz klienci_hash , podaje liczb ¦ zam ó wie « z ª o » onych przez klient ó w mieszkaj ¡ cych w Warszawie , Bia ª ymstoku , Lublinie lub Radomiu . SELECT COUNT (*) liczba_zamowien FROM zamowienia_inter z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ' );

80

Tablica 15: Czas wykonania zapyta« testowych (mierzony w ms) dla tabeli zamo-

wienia_inter o 60 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

16166

10615

18976

14573

2

458

738

2001

1435

3

473

432

5390

6177

4

2094

2077

3685

1843

5

167031

1261140

171135

156379

6

52849

406125

31948

30094

Tablica 16: Czas wykonania zapyta« testowych (mierzony w ms) dla tabeli zamo-

wienia_inter o 90 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

137638

6842

14300

9812

2

37835

41980

51207

35207

3

4981

2187

2391

2082

4

4825

52842

12983

4290

5

201742

238713

220820

213623

6

165309

1763925

144712

155926

81

Tablica 17: Czas wykonania zapyta« testowych (mierzony w ms) dla tabeli zamo-

wienia_inter o 120 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

141682

4927

13564

10981

2

6411

6981

9450

6004

3

7208

3562

3552

3823

4

7375

22760

23490

15073

5

281302

267354

259671

275453

6

250385

272880

171807

187083

Zapytanie nr 2 dla wszystkich rozmiarów tabeli i wszystkich konguracji indeksów zamowienia_inter zostaªo wykonane szybciej w stosunku do niepartycjonowanej tabeli zamowienia. Ten wzrost efektywno±ci jest spowodowany mechanizmem przycinania partycji, gdy» jedyny warunek selekcji tego zapytania dotyczy klucza partycjonowania tabeli zamowienia_inter. Przeszukiwane s¡ tylko dwie partycje tabeli zamiast caªej. Równie» zapytanie nr 4 dla indeksów innych ni» z globalnym partycjonowanym metod¡ mieszaj¡c¡ zwraca wyniki w krótszym czasie. Co ciekawe zapytanie nr 6 mimo braku dodatkowych mechanizmów wspomagaj¡cych oprócz zrównoleglenia zapytania, wykonuje si¦ szybciej ni» dla tabeli zamowienia we wszystkich konguracjach oprócz dla rozmiaru tabeli 60 mln wierszy, kiedy indeks na kluczu obcym nie jest partycjonowany.

82

Rysunek 19: Plan wykonania zapytania nr 2 dla tabeli zamowienia_inter o 60 mln wierszy, potwierdzaj¡cy u»ycie mechanizmu zrównoleglenia i przycinania partycji.

4.7 Tabela zam_inter_list Wyniki testów (wykonanych przez aplikacj¦ testow¡) na tabeli zam_inter_list partycjonowanej interwaªowo na kolumnie data_zam oraz nast¦pnie listowo na kolumnie wirtualnej region zostaªy przedstawione w Tablicy 18, Tablicy 19 oraz Tablicy 20. Kolumny tych tablic wskazuj¡ sposób indeksowania tabeli zam_inter_list w danym przypadku testowym. Kolejno nazwy tych kolumn oznaczaj¡:



bez indeksów - tylko globalny niepartycjonowany indeks na kluczu gªównym

id_zamowienia ;



globalny niepartycjonowany - z globalnym niepartycjonowanymi indeksami na kluczu gªównym, obcym id_klienta.



globalny partycjonowany - z niepartycjonowanymi indeksem na kluczu gªównym, partycjonowanym oraz globalnym drzewiastym partycjonowanym metod¡ mieszaj¡c¡ na bazie klucza obcego id_klienta.



z lokalnymi - z globalnym niepartycjonowanym indeksem na kluczu gªównym i z partycjonowanym lokalnie drzewiastym na kluczu obcym id_klienta ;

Dokªadny opis tabeli zam_inter_list zostaª zamieszczony we wcze±niejszej cz¦±ci pracy, w podrozdziale 3.3.5 Partycjonowanie dwupoziomowe interwaªowo-listowe.

83

Mierzono czas wykonania nast¦puj¡cych zapyta«:

1. Zapytanie zwraca liczb ¦ zam ó wie « z ª o » onych w regionie " WEST " . SELECT COUNT (*) FROM zam_inter_list WHERE region = ' WEST '; 2. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « z okresu jednego miesi ¡ ca . SELECT SUM ( kwota ) FROM zam_inter_list WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )); 3. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « dla wybranego klienta z okresu jednego miesi ¡ ca . SELECT sum ( kwota ) FROM zam_inter_list WHERE id_klienta = 123456 AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -03 -2014 ' , 'DD - MM - YYYY ' )); 4. Zapytanie zwraca ± redni ¡ sum ¦ warto ± ci zamowie « z okresu trzech miesi ¦ cy w regionie " CENTER " . SELECT AVG ( kwota ) FROM zam_inter_list WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -05 -2014 ' , 'DD - MM - YYYY ' )) AND region = ' CENTER '; 5. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zam_inter_list oraz klienci_hash , zwraca sum ¦ warto ± ci zamowie « dla ka » dego z klient ó w z okresu jednego miesi ¡ ca . SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien FROM zam_inter_list z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )) GROUP BY k . nazwisko ; 6. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zam_inter_list oraz klienci_hash , podaje liczb ¦ zam ó wie « z ª o » onych przez klient ó w mieszkaj ¡ cych w Warszawie , Bia ª ymstoku , Lublinie lub Radomiu . SELECT COUNT (*) liczba_zamowien FROM zam_inter_list z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ' );

84

Tablica

18:

Czas

wykonania

zapyta«

testowych

(mierzony

w

ms)

dla

tabeli

zam_inter_list o 60 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

14536

32099

40375

30056

2

5927

16718

18542

6529

3

5567

3088

9494

4979

4

1442

7229

8480

1740

5

205062

265974

179969

169422

6

84734

130104

147224

29203

Tablica

19:

Czas

wykonania

zapyta«

testowych

(mierzony

w

ms)

dla

tabeli

zam_inter_list o 90 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

16529

33839

40934

38301

2

7620

16963

19002

6027

3

6726

7109

7310

6110

4

2290

7531

8952

2105

5

414935

398618

42811

439112

6

176012

164091

179981

158713

85

Tablica

20:

Czas

wykonania

zapyta«

testowych

(mierzony

w

ms)

dla

tabeli

zam_inter_list o 120 mln wierszy i ro»nych konguracjach indeksowych.

nr zapytania

bez

globalny

globalny

z

indeksów [ms]

niepartycjonowany

partycjonowany

[ms]

[ms]

[ms]

lokalnymi

1

18219

36509

42910

41981

2

9176

17890

19876

7564

3

11849

7104

7526

8697

4

2901

8812

9801

2598

5

507614

458588

521766

530953

6

281239

277046

295627

189963

Dzi¦ki temu, »e tabela zam_inter_list jest partycjonowana dwupoziomowo, zapytanie nr 4 z dwoma warunkami w kluzuli WHERE dotycz¡cymi kluczy partycjonowania, mo»e by¢ wykonane z u»yciem podwójnego przycinania partycji. Dla tabeli

zam_inter_list o 60 mln wierszy zpytanie to jest przetwarzane krócej dla indeksów lokalnych albo tylko z globalnym niepartcjonowanym indeksem klucza gªównego. W przypadku rozmiarów równych 90 i 120 mln wierszy wszystkie konguracje indeksów u»yte w testach pozwalaj¡ uzyka¢ szybciej rezulataty zapytania ni» dla niepartycjonowanej tabeli zamowienia. Dla 90 i 120 mln wierszy wszystkie konguracje indeksów tabeli zam_inter_list pozwalaj¡ na szybsze otrzymanie wyników równie» zapytania nr 6. Szczególnie du»y zysk odnosi si¦ w przypadku zastosowania indeksu lokalnego na kluczu obcym id_klienta. Warto równie» zwrócic uwag¦ na to, »e mimo i» metoda partycjonowania tabeli zam_inter_list pozwala na przycinanie partycji na podstawie kolumny data_zam, to najlepszy wyniki otrzymujemy w odniesieniu do zapyta«, które mog¡ przycina¢ równie» subpartycje. Dla zapytania z warunkiem dotycz¡cym tylko kolumny data_zam bardziej opªacalne okazaªo sie zastosowanie tabeli zamowienia_inter.

86

4.8 Tabela zam_range_hash Wyniki testów (wykonanych przez aplikacj¦ testow¡) na tabeli zam_range_hash partycjonowanej dwupoziomowo, zakresowo na kolumnie data_zam oraz nast¦pnie metod¡ mieszaj¡c¡ na kluczu obcym id_klienta, zostaªy przedstawione w Tablicy 21, Tablicy 22 oraz Tablicy 23. Kolumny tych tablic wskazuj¡ sposób indeksowania tabeli zam_range_hash w danym przypadku testowym. Nazwy kolumn oznaczaj¡:



bez indeksów - tylko globalny niepartycjonowany indeks na kluczu gªównym

id_zamowienia ;



z lokalnymi - z globalnym niepartycjonowanym indeksem na kluczu gªównym, z partycjonowanymi lokalnie indeksami bitmapowym na kolumnie region oraz drzewiastym na kluczu obcym id_klienta ;

Dokªadny opis tabeli zam_range_hash zostaª zamieszczony we wcze±niejszej cz¦±ci pracy, w podrozdziale 3.3.6 Partycjonowanie dwupoziomowe zakresowo-mieszaj¡ce. Mierzono czas wykonania nast¦puj¡cych zapyta«:

1. Zapytanie zwraca liczb ¦ zam ó wie « z ª o » onych w regionie " WEST " . SELECT COUNT (*) FROM zam_range_hash WHERE region = ' WEST '; 2. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « z okresu jednego miesi ¡ ca . SELECT SUM ( kwota ) FROM zam_range_hash WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )); 3. Zapytanie zwraca sum ¦ warto ± ci zam ó wie « dla wybranego klienta z okresu jednego miesi ¡ ca . SELECT sum ( kwota ) FROM zam_range_hash WHERE id_klienta = 123456 AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -03 -2014 ' , 'DD - MM - YYYY ' )); 4. Zapytanie zwraca ± redni ¡ sum ¦ warto ± ci zamowie « z okresu trzech miesi ¦ cy w regionie " CENTER " . SELECT AVG ( kwota ) FROM zam_range_hash WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -02 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -05 -2014 ' , 'DD - MM - YYYY ' )) AND region = ' CENTER '; 5. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zam_range_hash oraz klienci_hash , zwraca sum ¦ warto ± ci zamowie « dla ka » dego z klient ó w z okresu jednego miesi ¡ ca . SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien 87

FROM zam_range_hash z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND z . data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )) GROUP BY k . nazwisko ; 6. Zapytanie wymagaj ¡ ce z ª ¡ czenia tabeli zam_range_hash oraz klienci_hash , podaje liczb ¦ zam ó wie « z ª o » onych przez klient ó w mieszkaj ¡ cych w Warszawie , Bia ª ymstoku , Lublinie lub Radomiu . SELECT COUNT (*) liczba_zamowien FROM zam_range_hash z , klienci_hash k WHERE z . id_klienta = k . id_klienta AND k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ' );

Tablica

21:

Czas

wykonania

zapyta«

testowych

(mierzony

w

ms)

dla

tabeli

dla

tabeli

zam_range_hash o 60 mln wierszy i dwóch konguracjach indeksowych.

Tablica

nr zapytania

bez indeksów [ms]

z lokalnymi [ms]

1

49198

6296

2

469

25026

3

144

1520

4

1916

34348

5

34494

78042

6

47234

66208

22:

Czas

wykonania

zapyta«

testowych

(mierzony

w

ms)

zam_range_hash o 90 mln wierszy i dwóch konguracjach indeksowych.

nr zapytania

bez indeksów [ms]

z lokalnymi [ms]

1

51981

12871

2

1871

27800

3

281

2301

4

2319

3412

5

54981

82616

6

49896

84941

88

Tablica

23:

Czas

wykonania

zapyta«

testowych

(mierzony

w

ms)

dla

tabeli

zam_range_hash o 120 mln wierszy i dwóch konguracjach indeksowych.

nr zapytania

bez indeksów [ms]

z lokalnymi [ms]

1

52987

18967

2

2876

35610

3

1180

3021

4

5410

4037

5

65387

87123

6

76001

104652

Tabela zam_range_hash osi¡gn¦ªa lepsze wyniki od niepartycjonowanej tabeli

zamowienia tylko dla zapytania nr 6. Jednak w stosunku do reszty tabel partycjonowanych szybciej zostaªo wykonane zapytanie nr 3, szczególnie bior¡c pod uwag¦ pierwsz¡ konguracj¦ - tylko niepartycjonowany indeks na kluczu gªównym. Dochodzi tu do przycinania partycji na dwóch poziomach zgodnie z kluczami partycjonowania i subpartycjonowania. Równie» dobre wyniki w porównaniu do innych metod partycjonowania zostaªy uzyskane dla zapytania nr 5. Mamy tu doczynienia z jednoczesnym przycinaniem partycji po kolumnie data_zam oraz zª¡czeniami na poziomie partycji. Na pocz¡tku zostaje wyselekcjonowna partycja do której nale»¡ daty nale»¡ce do przedziaªu z warunku WHERE zapytania, a potem dokonywane s¡ zª¡czenia mi¦dzy wybranymi subpartycjami tabeli zam_range_hash i partycjami tabeli klienci_hash.

89

Rysunek 20: Plan wykonania zapytania nr 5 dla tabeli zam_range_hash o 60 mln wierszy, wykorzystanie dwóch mechanizmów poprawiaj¡cych wydajno±¢ - przycinania partycji oraz zª¡cze« na poziomie partycji.

90

4.9 Wnioski z bada« testowych Przeprowadzone testy potwierdziªy tez¦, »e partycjonowanie daje tym wi¦ksze korzy±ci im wi¦kszyh dotyczy tabel. Przy maªych rozmiarach tabel, ze wzgl¦dy na efektywno±c wykonywania zapyta«, cz¦sto nie ma sensu tworzy¢ partycji. Zwykle wystarcz¡ m¡drze dodane niepartycjonowane indeksy. Wa»ne jest równie», aby w przemy±lany sposób dobiera¢ metod¦ partycjonowania, poniewa» ¹le dopasowana mo»e przynie±¢ skutki przeciwne do zamierzonych. Przeprowadzone w ramach tej pracy badania wykazaªy, »e zapytania bez warunków selekcji czy zª¡cze« opartych na kluczach partycjonowania wykonywane s¡ nawet kilkukrotnie dªu»ej w stosunku do tabel niepartycjonowanych. Czasem równie» dla wi¦kszych tabel partycjonowanie mo»e okaza¢ si¦ zb¦dne. W czasie wykonywania testów zaobserwowano, »e dla rozmiaru tabel równego 90 i 120 mln wierszy zapytanie:

SELECT COUNT (*) FROM zamowienia_list WHERE region = ' WEST '; mimo, »e jest wykonywane dla tabeli zamowienia_list z u»yciem mechanizmu przycinania partycji, to jednak szybciej zwraca rezultaty dla tabeli zamowienia z indeksem bitmapowym na kolumnie region, która jest kluczem partycjonowania tabeli zamo-

wienia_list. Warto zwróci¢ uwag¦, »e w tym przypadku zostaje skanowana jedna z pi¦ciu partycji tabeli zamowienia_list, ale te partycje rosn¡ª wraz ze wzrostem liczby rekordów tabeli. Przy 90 i 120 mln wierszy bardziej efektywny staje si¦ indeks bitmapowy. W przypadku partycjonowania tabel najlepsze rezultaty otrzymuje si¦ przy zapytaniach korzystaj¡cych z kolumn, które s¡ kluczami partycjonowania. Najkorzystniej jest, gdy klucze partycjonowania brane s¡ pod uwag¦ we wszystkich warunkach selekcji zapytania, co umo»liwia skorzystanie z najefektywniejszego mechanizmu przycinania partycji. Zª¡czenia s¡ wykonywane najszybciej dla tabel partycjonowanych metod¡ referencyjn¡ lub takich, których klucze partycjonowania s¡ zgodne z kluczami zª¡czenia. Sposobem na uzyskanie zª¡czenia na poziomie partycji oraz przycinania partycji jest stworzenie tabeli partycjonowanej dwupoziomowo, tak aby jej klucz partycjonowania nale»aª do warunku selekcji w klauzuli where zapytania i dodatkowo byªa subpartycjonowana na kluczu zª¡czenia. Zale»no±ci te widoczne s¡ równie» w wynikach testów. Korzystny wpªyw przycinania partycji mo»na byªo

91

zaobserwowa¢ np. przy zapytaniu:

SELECT SUM ( kwota ) FROM zamowienia_inter WHERE data_zam BETWEEN ( TO_DATE ( ' 01 -06 -2014 ' , 'DD - MM - YYYY ' )) AND ( TO_DATE ( ' 01 -07 -2014 ' , 'DD - MM - YYYY ' )); kiedy dla ka»dej z trzech wielko±ci (60, 90 120 mln wierszy) tabeli zamowienia_inter otrzymano kilkukrotnie lepsze wyniki czasowe w porównaniu z tabel¡ niepartycjonowan¡. Pozytywny wpªyw zª¡cze« na poziomie partycji oraz zrównoleglenia wykonania byª szczególnie widoczny dla tabel klienci_ref i zamowienia_ref. Zapytanie:

SELECT COUNT (*) liczba_zamowien FROM zamowienia_ref z , klienci_ref k WHERE z . id_klienta = k . id_klienta AND k . miasto IN ( ' WARSZAWA ' , ' BIALYSTOK ' , ' LUBLIN ' , ' RADOM ' ); dla wszystkich rozmiarów testowanych tabel zostaªo szybciej wykonane w przypadku tabel partycjonowanych referencyjnie. Dla tabeli klienci_ref o 60 mln wierszy i za-

mowienia_ref o 120 mln wierszy i zastosowaniu indeksów partycjonowanych lokalnie zapytanie zwróciªo wyniki o 57% szybciej ni» dla tabeli niepartycjonowanej. Partycjonowanie indeksów jest bardziej skomplikowane. Ci¦»ko jest stworzy¢ jednoznaczn¡ reguª¦, kiedy warto stosowa¢ partycjonowanie indeksów i jak dopasowa¢ metod¦. Równie» w dokumentach Oracle dotycz¡cych partycjonowania, mo»na wyczyta¢, »e podj¦cie decyzji o sposobie partycjonowania najlepiej poprzedzi¢ testami. W ten sposób mo»emy uzyska¢ pewno±¢, »e spowodujemy wzrost w wydajno±ci wykonywania zapyta«. W ramach tej pracy partycjonowanie byªo gªównie sprawdzane pod k¡tem szybko±ci wykonania zapyta« typy SELECT. Testy wykazaªy, »e najbezpieczniej jest stosowa¢ indeksy niepartycjonowane lub partycjonowane lokalnie. Jak wskazaªam w cz¦±ci teoretycznej pracy, partycjonowanie globalne mo»e sta¢ si¦ uci¡»liwe, jesli regularnie wykonuje si¦ operacje administratorskie dotycz¡ce przenoszenia partycji, usuwania du»ych fragmentów danych itp.. Ci¦»ko mi jednak byªo zasymulowa¢ ±rodowisko wielodost¦powe, z wieloma jednoczesnymi transakcjami, a wtedy wg dokumentacji Oracle, partycjonowanie globalne przynosi najwi¦ksze korzy±ci.

92

5

Podsumowanie Celem niniejszej pracy in»ynierskiej byªo zapoznanie sie z opcj¡ partycjonowania

tabel i indeksów w Oracle Database 11gR2 i przeprowadzenie bada« nad efektywno±ci¡ wykonywania ró»nego typu zapyta« na partycjonowanych obiektach. Autorka zawarªa w pracy wst¦p teoretyczny zawieraj¡cy najwa»niejsze infromacje dotycz¡ce opisywanej opcji. Przedstawiªa mechanizmy wspomagaj¡ce efektywno±¢ partycjonowania oraz wskazaªa jego potencjalne zastosowania. W ramach bada« skongurowane zostaªo ±rodowisko badawcze z uwzgl¦dnieniem napisania generatorów danych testowych oraz aplikacji sprawdzaj¡cej czas wykonania ka»dego z zapyta« testowych na ró»nych kombinacja partycjonowanych tabel oraz indeksów. Wyniki testów zostaªy przedstawione i nast¦pnie podsumowane. Potwierdziªy si¦ tezy stawiane przez rm¦ Oracle w dokumentacji opcji partycjonowania. Partycjonowanie jest relatywnie prostym mechanizmem mog¡cym znacznie poprawi¢ wydajno±c bazy danych na wielu obszarach. Zarz¡dzanie partycjonowanymi obiektami najcz¦±ciej jest bardzo wygodne, a korzy±ci jakie przynosi ta opcja mog¡ pozytywnie zaskakiwa¢. Testy wykonane w ramach tej pracy wykazaªy, »e zastosowanie partycjonowania w odniesieniu do konkretnych zapyta«, mo»e spowodowa¢ nawet kilkukrotne przyspieszenie ich wykonania. Wydaje si¦, »e partycjonowanie tabel i indeksów mo»e by¢ dobr¡ odpowiedzi¡ na wspóªczesne problemy z magazynowaniem i przetwarzaniem ogromnych zbiórów danych. Nale»y jednak pami¦ta¢, »e ¹le dobrane metody partycjonowania lub zastowanie tej techniki w stosunku do wzgl¦dnie maªych tabel mo»e mie¢ negatywny wpªyw na dziaªanie bazy. Wyniki opisanych w tym dokumencie bada« wskazuj¡, »e decyzj¦ o wyborze metody partycjonowania warto podejmowa¢ na bazie znajomo±ci typów zapyta« jakie b¦d¡ wykonywane w systemie oraz poprze¢ wcze±niej przeprowadzonymi testami. W czasie realizacji pracy in»ynierskiej dyplomantka miaªa okazj¦ znacznie poszerzy¢ swoja wiedz¦ nie tylko na temat opcji partycjonowania, ale równie» sposobu dziaªania systemu i wielu mechanizmów wyst¦puj¡cych w systemie Oracle Database. Szczególnie cenne byªo zapoznanie si¦ z metodami optymalizacji zapyta« i skutkami zastosowania ró»nych planów wykonania. Zdobyªa równie» podstawowe umiej¡tno±ci administrowania baz¡ danych Oracle oraz dowiedziaªa si¦, sk¡d czerpa¢ cenne i wiarygodne informacje dotycz¡ce tego systemu.

93

Literatura [1]

http://www.oracle.com/technetwork/database/bi-datawarehousing/twp-partitioning-11gr22010-10-189137.pdf

[2]

http://docs.oracle.com/cd/E11882_01/server.112/e25523/partition.htm

[3]

http://www.oracle.com/us/corporate/oracle-fact-sheet-079219.pdf

[4]

https://www.sec.gov/Archives/edgar/data/1341439/000119312513272832/0001193125-13272832-index.htm

[5]

https://www.ycharts.com/companies/ORCL/r_and_d_expense

[6]

Arup Nanda

[7]

https://blogs.oracle.com/datawarehousing/entry/compressing_individual_partiti

[8]

https://blogs.oracle.com/datawarehousing/entry/managing_optimizer_statistics

[9]

http://structureddata.org/2008/07/16/oracle-11g-incremental-global-statistics-on-

Nonstop Partition Operations,

Oracle Magazine, May/June 2014

partitioned-tables/

[10]

http://docs.oracle.com/cd/E11882_01/server.112/e25523/part_avail.htm

[11]

http://docs.oracle.com/cd/B28359_01/server.111/b28313/usingpe.htm

[12]

http://docs.oracle.com/cd/E11882_01/server.112/e25523/part_admin005.htm

[13]

http://www.oracle.com/technetwork/database/bi-datawarehousing/twp-explain-theexplain-plan-052011-393674.pdf

[14]

http://docs.oracle.com/cd/B28359_01/server.111/b28313/usingpe.htm

[15]

http://psoug.org/reference/dbms_random.html

[16]

http://www.dba-oracle.com/t_11g_new_virtual_column.htm

[17]

Bob Bryla, Kevin Loney [tª. Piotr Pilch],

danych, [18]

Oracle database 11g: podr¦cznik administratora baz

Helion, 2010

Robert G. Freeman, Arup Nanda [tª. Kamila Primke],

Helion, 2009

94

Oracle database 11g: nowe mo»liwo±ci,

A

Zaª¡cznik A - kod ¹ródªowy aplikacji testowej Poni»ej znajduje si¦ kod ¹ródªowy aplikacji testowej Polaczenie.java. W tym

przykªadzie aplikacja nawi¡zuje poª¡czenie z baz¡ danych tbtest z maszyny orem1.ii.pw.edu.pl. Wykonywane s¡ zapytania na tabelach KLIENCI oraz ZAMOWIENIA.

1

import java . sql .*;

2

import java . util . Properties ;

3

import java . util . logging . Level ;

4

import java . util . logging . Logger ;

5

import java . io . PrintWriter ;

6 7 8 9 10

public class Polaczenie { public void polaczenie_z_baza () { String orem1 = " jdbc : oracle : thin : @orem1 . ii . pw . edu . pl :1521: dbtest " ; String orem2 = " jdbc : oracle : thin : @orem2 . ii . pw . edu . pl :1521: dbtest2 " ;

11 12

String buffer = " ALTER SYSTEM FLUSH BUFFER_CACHE " ;

13

String shared = " ALTER SYSTEM FLUSH SHARED_POOL " ;

14

String query1 = " SELECT COUNT (*) FROM klienci WHERE miasto = ' KATOWICE '" ;

15

String query2 = " SELECT COUNT (*) FROM zamowienia WHERE region = ' WEST '" ;

16

String query3 = " SELECT SUM ( kwota ) FROM zamowienia " +

17

" WHERE data_zam BETWEEN ( TO_DATE ( '01 -06 -2014 ' , 'DD - MM - YYYY ')) " +

18

" AND ( TO_DATE ( '01 -07 -2014 ' , 'DD - MM - YYYY ')) " ;

19

String query4 = " SELECT sum ( kwota ) FROM zamowienia " +

20

" WHERE id_klienta = 123456 AND " +

21

" z . data_zam BETWEEN ( TO_DATE ( '01 -02 -2014 ' , 'DD - MM - YYYY ')) " +

22

" AND ( TO_DATE ( '01 -03 -2014 ' , 'DD - MM - YYYY ')) " ;

23

String query5 = " SELECT AVG ( kwota ) FROM zamowienia

" +

24

" WHERE data_zam BETWEEN ( TO_DATE ( '01 -02 -2014 ' , 'DD - MM - YYYY ')) " +

25

" AND ( TO_DATE ( '01 -05 -2014 ' , 'DD - MM - YYYY ')) AND region = ' CENTER '" ;

26

String query6 = " SELECT k . nazwisko , sum ( z . kwota ) wartosc_zamowien " +

27

" FROM zamowienia z , klienci k

28

" z . data_zam BETWEEN ( TO_DATE ( '01 -06 -2014 ' , 'DD - MM - YYYY ')) " +

29

" AND ( TO_DATE ( '01 -07 -2014 ' , 'DD - MM - YYYY ')) GROUP by k . nazwisko " ;

30

WHERE z . id_klienta = k . id_klienta AND " +

String query7 = " SELECT k . nazwisko , COUNT (*) liczba_zamowien " +

31

" FROM zamowienia z , klienci k WHERE z . id_klienta = k . id_klienta AND " +

32

" k . miasto IN ( ' WARSZAWA ', ' BIALYSTOK ', ' LUBLIN ', ' RADOM ') " ;

95

33

try

34

{

35

DriverManager . registerDriver ( new oracle . jdbc . driver . OracleDriver ());

36

System . out . println ( " Sterowniki zaladowane " );

37

Connection conn = null ;

38

try {

39

Properties props = new Properties ();

40

props . put ( " user " , " SYS " );

41

props . put ( " password " , " Kwasia04 " );

42

props . put ( " internal_logon " , " SYSDBA " );

43

conn = DriverManager . getConnection ( orem1 , props );

44

}

45

catch ( SQLException ex ) { Logger . getLogger ( Polaczenie . class . getName ()). log ( Level . SEVERE ,

46

" nie udalo sie

47

polaczyc

z baza

danych " , ex );

System . exit ( -1);

48 49

}

50

System . out . println ( " Polaczenie nawiazane " );

51

Statement stm = null ;

52

PrintWriter zapis = new PrintWriter ( " dane . txt " );

53

try {

54

conn . setAutoCommit ( false );

55

stm = conn . createStatement ();

56

stm . executeUpdate ( buffer );

57

stm . executeUpdate ( shared );

58 59

test ( stm , query1 , zapis );

60

test ( stm , query2 , zapis );

61

test ( stm , query3 , zapis );

62

test ( stm , query4 , zapis );

63

test ( stm , query5 , zapis );

64

test ( stm , query6 , zapis );

65

test ( stm , query7 , zapis );

66

conn . commit ();

67

}

68

catch ( SQLException ex ) {

69

System . out . println ( " Blad wykonania polecenia " + ex . toString ());

70

conn . rollback ();

71

} 96

72

finally {

73

zapis . close (); if ( stm != null ) {

74

try {

75 76

stm . close ();

77

System . out . println ( " Statement zamkniety " ); } catch ( SQLException e )

78

{ System . out . println ( " Nie udalo sie zamknac res . " +

79

e . toString ());}

80 81

}

82

if ( conn != null ) { try {

83 84

conn . close ();

85

System . out . println ( " Polaczenie zakonczone " ); } catch ( SQLException e )

86

{ System . out . println ( " Nie udalo sie zamknac stm . "

87

+ e . toString ());}

88

}

89

}

90 91

}

92

catch ( Exception e ) {

93

System . out . println ( " Blad " );

94

e . printStackTrace (); }

95

}

96 97 98

private void test ( Statement stm , String query , PrintWriter zapis ) throws Exception

99 100

{

101

long start = System . currentTimeMillis ();

102

ResultSet res = stm . executeQuery ( query );

103

long time = System . currentTimeMillis () - start ;

104 105

res . close ();

106

System . out . println ( " Czas : " + time + " ms dla zapytania " + query + " ; " );

107

zapis . println ( " Czas : " + time + " ms dla zapytania " + query + " ; " + '\ n ' );

108

}

109 110

97

111

public static void main ( String [] args ){

112

Polaczenie oracle = new Polaczenie ();

113

oracle . polaczenie_z_baza ();

114

}

115

}

98