UNICORN COLLEGE BAKALÁŘSKÁ PRÁCE

Transkript

UNICORN COLLEGE BAKALÁŘSKÁ PRÁCE
UNICORN COLLEGE
Katedra informačních technologií
BAKALÁŘSKÁ PRÁCE
Nástroj na tvorbu testovacích dat
pro zátěžové testování DB
Autor BP: Marek Chytrý
Vedoucí BP: Ing. Miroslav Žďárský
2012 Praha
ČESTNÉ PROHLÁŠENÍ
Prohlašuji, že svoji bakalářskou práci na téma Nástroj na tvorbu testovacích dat pro
zátěžové testování DB jsem vypracoval samostatně pod vedením vedoucího bakalářské
práce a s použitím odborné literatury a dalších informačních zdrojů, které jsou v práci
citovány a jsou též uvedeny v seznamu literatury a použitých zdrojů.
Jako autor uvedené bakalářské práce dále prohlašuji, že v souvislosti s vytvořením této
bakalářské práce jsem neporušil autorská práva třetích osob, zejména jsem nezasáhl
nedovoleným způsobem do cizích autorských práv osobnostních, a jsem si plně vědom
následků porušení ustanovení § 11 a následujících autorského zákona č. 121/2000 Sb.
V ........................... dne ................
….……………
Marek Chytrý
PODĚKOVÁNÍ
Děkuji vedoucímu bakalářské práce Ing. Miroslavovi Žďárskému za účinnou metodickou,
pedagogickou a odbornou pomoc a další cenné rady při zpracování mé bakalářské práce.
Dále chci velmi poděkovat své manželce za oporu, povzbuzení a vytvoření příjemného
prostředí pro psaní této práce a rodičům, kteří mi umožnili studium a během studia mě
podporovali.
NÁSTROJ NA TVORBU TESTOVACÍCH
DAT PRO ZÁTĚŽOVÉ TESTOVÁNÍ DB
TOOL FOR CREATING TEST DATA
FOR STRESS TESTING DB
6
ABSTRAKT
Cílem této bakalářské práce je navrhnout nástroj na generování dat pro zátěžové testy. Aby
však tato data byla správně navržena, je potřeba porozumět databázi, jak s daty pracuje a
jak můžeme na základě správného návrhu datové struktury tuto činnost co nejvíce
zefektivnit.
V teoretické části jsou nejprve popsány základní pojmy týkající se relačních databází
a zátěžových testů. Poté jsou vysvětleny způsoby sběru dat z databáze a je ukázáno
na příkladech, jak lze příkazy pro práci s daty optimalizovat. Dále navazují informace
o způsobech, jak databáze volí co nejefektivnější přístup k datům za použití optimizeru
a statistik databáze. Práce se nezaměřuje na konfiguraci databáze nebo hardwaru serveru,
to by bylo už na téma jiné bakalářské práce.
V praktické části je pak popsán navržený nástroj pro generování dat, jeho části a princip
generování testovacích dat. Zde je také základně popsán jazyk PL/SQL, ve kterém je
nástroj naprogramován.
Klíčová slova: relační databáze, zátěžové testy, optimalizace, optimizer, statistiky, PL/SQL
7
ABSTRACT IN ENGLISH
The aim of this bachelor thesis is to propose a tool for generating data for stress tests. In
order that this data are properly designed, it is necessary to understand the database; how it
works with data and how we can do this activity more effective based on right proposal of
the data structure.
In the theoretical section there are firstly described the basic concepts related to relational
databases and stress tests. Then there is explained how we collect data from the database
and shown in the examples, how the commands for working with data can be optimized.
Further follow information how database chooses the most effective access to data using
the optimizer and statistics database. The thesis does not focus on the configuration
database or hardware; it would be the topic of another thesis.
In the practical part there is described a tool designed to generate data, its parts and
principles of generating test data. There is also described programming language PL/SQL,
in which the tool is programmed.
Keywords: relational database, stress tests, optimization, optimizer, statistics, PL/SQL
8
OBSAH
1.
Úvod .................................................................................................................. 11
2.
Základní pojmy k optimalizaci databází ........................................................... 12
2.1.
Databáze .................................................................................................. 12
2.1.1.
2.2.
Zátěžové testy .......................................................................................... 15
2.2.1.
2.3.
Exekuční plán ................................................................................. 18
Indexy ...................................................................................................... 21
2.4.1.
B-Tree index................................................................................... 21
2.4.2.
Bitmap index .................................................................................. 26
2.4.3.
Indexově organizované tabulky (Index organized tables) ............. 28
2.5.
Optimizer ................................................................................................. 30
2.5.1.
3.
Získání dat pro testování ................................................................ 15
Přístupy k tabulkám ................................................................................. 16
2.3.1.
2.4.
Relační databáze............................................................................. 13
RBO (Rule based optimizer) a CBO (Cost based optimizer) ........ 31
2.6.
Statistiky .................................................................................................. 34
2.7.
Hinty ........................................................................................................ 37
Praktická část - Generování dat ........................................................................ 38
3.1.
Úvod do PL/SQL ..................................................................................... 38
3.1.1.
3.2.
Balíčky, procedury a funkce .......................................................... 38
Princip generování ................................................................................... 43
3.2.1.
Zdrojová data pro generování ........................................................ 43
3.2.2.
Balíček fetch_source_data ............................................................. 44
9
3.2.3.
Balíček random_data ...................................................................... 46
3.2.4.
Balíček package_random_table ..................................................... 47
3.2.5.
Pomocné balíčky, funkce a procedury ........................................... 50
3.3.
Export a import velkého množství dat v databázích Oracle .................... 51
4.
Závěr ................................................................................................................. 52
5.
Conclusion ........................................................................................................ 54
6.
Zdroje ................................................................................................................ 56
7.
Seznam použitých symbolů a zkratek ............................................................... 58
8.
Seznam obrázků ................................................................................................ 59
9.
Seznam tabulek ................................................................................................. 60
10
1.
ÚVOD
Vysoká dostupnost a krátká doba odezvy informačních systémů se v dnešním světě
pokládá za samozřejmost. Pokud se některá internetová stránka nenačte uživateli do tří
sekund, uživatel pravděpodobně takovou stránku po této době zavře a podívá se raději po
jiné stránce, která se mu dostatečně rychle zobrazí. Tím narážím na fakt, že jedním z
nejdůležitějších vlastností informačního systému je jeho doba odezvy. Tato oblast
informačních technologií není jednoduchá, ale dnešní uživatelé předpokládají a berou za
samozřejmost, že vše probíhá bez velkých prodlev. Navíc požadavky na zajištění
dostupností a zvládání zátěží v době špiček je stanoveno v provozních smlouvách a
dokumentech SLA. Pokud jsou tato stanovení porušena, pak provozovatel informačního
systému neplatí jen ušlé zisky společností, ale může navíc platit i smluvní pokuty.
Na základě požadavků zajištění nabízeného výkonu je potřeba tyto vlastnosti systému
otestovat. A testování je zapotřebí nejen při zavádění systému, ale třeba i při změně
softwarových technologií. Podle internetového článku na System On-line (1) je zapotřebí
testovat výkon v těchto případech:
1. Výkonnostní akceptace řešení
2. Optimalizace hardwarové a softwarové konfigurace
3. Zjištění limitů hardwarové a softwarové konfigurace
4. Hledání úzkých míst již provozovaného systému
5. Ověření výkonnosti po změně technologie, po upgradu na novou verzi (operačního
systému, aplikace, databáze) nebo po významné změně konfigurace
Na vysoké škole Unicorn College jsem se seznámil s databází Oracle a její administrací a
také se způsoby testování. V obou kurzech byly probírány zátěžové testy, ale v každém
z jiného úhlu pohledu. Velmi mě zaujala myšlenka spojit informace z těchto kurzů a
vytvořit praktický nástroj pro generování dat pro zátěžové testy pro relační databáze.
11
2.
ZÁKLADNÍ POJMY K OPTIMALIZACI DATABÁZÍ
2.1. Databáze
Data v jakémkoliv systému je potřeba perzistentně ukládat, aby bylo možné je později
kdykoliv opět načíst. V jednoduchých systémech nebo domácích počítačích stačí na
uložení dat souborový systém, pokud ale potřebujete například:
1. Data rychle vyhledávat
2. Přistupovat k datům paralelně
3. Pokročilejší nastavení práv přístupů k datům
4. Vybírat pouze část z celé množiny dat podle potřeb uživatele systému.
V těchto případech souborový systém určitě nedostačuje a je potřeba použít databázi.
Databáze slouží primárně k trvalému uložení dat. Dnes navíc poskytuje mnohé pokročilé
funkce. Například zabezpečení, zálohování, archivaci, analýzu dat a další. Databáze je
jedna z nejdůležitějších částí systému, a proto je potřeba tuto oblast nezanedbat.
Většina lidí si pod pojmem databáze představí tabulky dat, ale toto je jen jeden typ
databází, relační databáze. Tyto databáze jsou tvořeny relacemi. Tento typ databází ale
není jediný, můžeme se ještě setkat s databázemi objektovými nebo objektově-relačními.
Objektové databáze neukládají data do tabulek, ale přímo ukládají objekty, se kterými
programátor pracuje. Proto pro programátory je mnohem intuitivnější ukládat jednotlivé
objekty tříd a nemuset se zamýšlet nad tabulkami nebo převodem objektů do tabulek.
Dalším možným přístupem je objektově-relační databáze. V tomto případě je potřeba
nejprve nadefinovat způsob převodu mezi tabulkami a objekty. Aby bylo možné objekty
do tabulky namapovat, zakládají se sloupce tabulky tak, aby odpovídaly jednotlivým
atributům třídy, jejichž objekty se mají do tabulky vložit. Jednotlivé řádky tabulky pak
odpovídají jednotlivým objektům. Tento přístup se snaží brát přednosti z obou zvýše
zmíněných typů databází, ale v konečném důsledku je náročné samotné mapování tabulek
na objekty a navíc musí programátoři popsat daný způsob mapování tabulek na objekty.
12
Tato práce se zaměřuje pouze na relační databáze, a konkrétně na relační databázi Oracle.
Pro tuto databázi jsou napsány i praktické příklady, a je pro ni primárně určen i nástroj pro
generování dat. Tato databáze je zároveň nejrozšířenější na trhu komerčních databází a je
používána pro rozsáhlé informační systémy.
V této bakalářské práci je pojem „databáze“ používán dvěma různými způsoby, a to jednak
tento pojem je používán ve smyslu trvalého úložiště dat a jednak ve smyslu komplexního
systému, který se stará o kompletní správu všech dat uložených v daném systému.
2.1.1. Relační databáze
Základem relačních databází jsou tabulky. Tabulky se skládají ze sloupců, ve kterých jsou
uloženy jednotlivé proměnné. Jednotlivé sloupce jsou pojmenovány tak, aby co nejlépe
vystihly data v nich uložená. Pro každý sloupec je definovaný datový typ, ten určuje, jaká
data jsou ve sloupci uložena. V jednotlivých řádcích jsou pak uložené jednotlivé záznamy.
Pro přístup k těmto datům se používá speciálně navržený jazyk SQL. Ten se skládá z
několika skupin příkazů, které jsou rozděleny podle svého účelu. Skupiny příkazů:
1. DDL (Data Definition Language) – příkazy pro definice struktur databáze –
tabulky, indexy
2. DML (Data Manipulation Language) – příkazy pro manipulaci s daty
3. DCL (Data Control Language) – příkazy pro řízení kontroly nad daty
4. TCC (Transaction Control Commands) – příkazy pro řízení transakcí
O každé skupině jazyků by mohly být napsány celé knížky. V této práci jsou jednotlivé
typy příkazů popsány pouze z pohledu optimalizace.
V teoretické části práce je popisována skupina příkazů DML. Hlavně je zde popsáno,
jakým způsobem databáze vrací řádky pro příkaz „SELECT“. Naváže kapitola o indexech,
které slouží ke zrychlení přístupu do tabulek databáze a spadají do skupiny příkazů DDL.
V praktické části pak bude popsáno, jakým způsobem budou generována data pro zátěžové
testy a také jak jsou vkládána do tabulek.
Data v tabulkách mohou mít velmi složitou strukturu a množství dat může být velmi
rozsáhlé. Pro správné navržení datových struktur je potřeba zohlednit mnoho faktorů a po
samotném navržení databázového systému je následně potřeba ověřit splnění požadavků.
13
Není možné zjistit až na produkci, že byla nevhodně navržena. Proto je maximálně důležité
ještě před jejím zavedením do ostrého provozu ověřit pomocí zátěžových testů, že je
schopna zpracovávat požadované objemy dat. (2)
14
2.2. Zátěžové testy
Testování výkonu a možné zátěže databázového systému není jednoduchá činnost a často
je zanedbávána nebo nedoceňovaná. Při práci na projektu pak bývá tato oblast nejčastěji ta,
která je z nedostatku buď finančních, nebo časových zdrojů zrušena. Přesto pokud je
požadován kvalitní software, má tato oblast nezastupitelné místo.
Univerzální návod na testování obecně bohužel neexistuje a myslet si, že informační
systémy neobsahují žádné chyby, také není správný přístup. Pokud jsme tedy již
rozhodnuti, že chceme testovat, musíme se následně zamyslet, co konkrétně a jakým
způsobem bude testováno. Rozhodně je také důležité vědět, z jakého důvodu budou testy
prováděny. Tato bakalářská práce se zaměřuje na testování výkonu a zjišťování jeho
možné optimalizace. Na základě znalostí o optimalizaci je pak navržen způsob efektivního
generování dat. Aby data byla věrná datům produkčním, je potřeba je vygenerovat
správným způsobem.
Generování dat není jediným způsobem, jak získat data pro databázi. Data je možno získat
i jinými způsoby.
2.2.1. Získání dat pro testování
Jednou z možností je přímo použít produkční data. Tato varianta je někdy používána, ale
není úplně vhodná kvůli velkému riziku zneužití těchto dat a musí být v takovém případě
přijata zvýšená bezpečnostní opatření. Toto řešení bývá voleno z důvodu jednoduchosti a
rychlosti získání dat, v případech kdy potřebujeme dodat data do druhého dne.
Dalším řešením je data masking. Tímto způsobem se použijí data produkční, ale
znehodnocená tak, aby nebylo možné je obnovit, ale struktura těchto dat je shodná s
produkčními daty. Viz obrázek 1.
Jinou možností je vlastní vygenerování dat. Takto získaná data musí odpovídat datům
reálným, co se týká hodnot a pravděpodobnosti opakování. Proto jsou tato data také
nejvěrnější datům reálným a navíc zde nejsou bezpečnostní rizika jako u použití
produkčních dat. Jinou obrovskou výhodou těchto dat je jejich volitelný rozsah. Pokud je
dat nedostatek, není problém je doplnit. Toto u předešlých způsobů není možné. Na druhou
stranu někdy může být obtížné získat pravděpodobnostní rozdělení dat, abychom dokázali
15
vygenerovat totožná data. Pokud ale tyto pravděpodobnosti rozdělení máme, získáváme
další nezanedbatelnou výhodu, a tou je možnost vygenerovat libovolně velkou množinu
dat, která odpovídá produkčním datům, a tímto způsobem se můžeme připravit na budoucí
zátěž databáze.
Obrázek 1: Data masking
LAST_NAME
SSN
SALARY
AGUILAR
203-33-3234
40 000
BENSON
323-22-2943
60 000
D SOUSA
989-22-2403
80 000
FI ORANO
093-44-3823
45 000
BIRTH_NUMBER
SALARY
ANSKELFD
111-23-1111
40 000
BEPFZPEFZ
111-34-1345
60 000
ERPVQAJEF
111-97-2749
80 000
GEPV
111-49-3849
45 000
LAST_NAME
Zdroj: Vlastní zpracování Visio 2007 podle zdroje: http://datamart.org/2010/03/12/data-masking/
Před popisem samotného generování bude popsán způsob zpracování příkazu od uživatele
přes možné teoretické optimalizace dat v databázi.
2.3. Přístupy k tabulkám
Přístupy do tabulky jsou způsoby, jakými jsou procházeny tabulky a vracena uživateli
požadovaná data. Aby bylo možné vykonávat zátěžové testy, je nutné porozumět, jak
databáze vyhledává žádaná data. Přístupů máme několik:
Full table scan (FTS)
Tento přístup načítá najednou všechna data z tabulek a následně je prochází, zda
odpovídají zadaným kritériím. Což samozřejmě představuje náročné I/O operace. Databáze
naštěstí data nenačítá postupně ale po blocích, čímž je načítání podstatně zrychleno. Tento
přístup je zvolen, pokud má být načtena například celá tabulka nebo pokud máme malé
množství dat a je rychlejší je všechna načíst, než je procházet pomocí některého z indexů.
16
Pokud nebyly nad sloupci tabulky vytvořeny indexy, nebo byly vytvořeny špatným
způsobem, pak se také použije tento přístup.
Rowid access
Tento přístup je použit v případě, když jsou rowid řádky známy a databáze načte konkrétní
blok, kde se požadovaná řádka přímo nachází. Proto se nejprve zjišťují rowid řádek
pomocí full table scanu nebo index scanu. Pokud by byly známy rowid řádky, mohla by
být zadána v podmínce where rowid = <řádek>, a poté by nebylo zapotřebí žádné další
prohledávání tabulek, ale to většinou není známo. Příklad příkazu, kdy je známa rowid a
databáze může k řádku přistoupit přímo přes ně:
SELECT * FROM emp WHERE rowid = chartorowid('AAAW07AAEAAAAI7AAA');
V příkazu byla použita funkce chartorowid, která slouží k převodu řetězce na rowid.
Index unique scan (IUS)
Index unique scan je přístup, který využívá indexů (indexy budou popsány v samostatné
kapitole). Tyto indexy jsou vloženy k některému ze sloupců tabulky a databáze v nich
vyhledává v případech, kdy je nad tímto sloupcem „WHERE podmínka“ a vyfiltrovaných
dat je malý počet.
Index range scan (IRS)
Tento přístup je podobný přístupu index unique scan, jen podle indexů nevyhledáváme
unikátní hodnoty, ale interval hodnot. Většinou v podmínce příkazu jsou horní a dolní
omezení pro vyhledávání v indexech.
Fast full index scan (FFIS)
Přístup je zvolen v případě, kdy hledaná hodnota je zároveň uložena v indexu a není
potřeba přistupovat do samotné tabulky. FFIS je velmi podobný přístupu Full table scan.
Stejně jako FTS načítá více bloků naráz, čímž urychluje získávání dat. Pokud je zvolen
tento přístup, odpadá druhá fáze rowid access, která se ve všech ostatních případech vždy
vykonává.
17
Databáze, pokud přistupuje k datům, jen zřídka volí pouze jeden přístup. Většinou volí
kombinaci dvou a více přístupů. Které přístupy a v jakém pořadí jsou zvoleny,
vyhodnocuje optimizer. Toto vyhodnocování je prováděno pro každý DML příkaz. Popis
přístupů a dalšího zpracování dat, které jsou vracena databází, popisuje podrobně exekuční
plán.
2.3.1. Exekuční plán
Tento plán se skládá z několika kroků a tyto kroky neobsahují pouhý výběr dat. Může se
jednat i o filtrování, řazení, seskupování nebo spojování tabulek. Exekuční plán je velmi
důležitý, abychom dokázali pochopit navržené postupy optimizerem a mohli identifikovat
případná slabá místa. Možné akce vykonávané v databázi a zobrazené v exekučním plánu:

Pořadí tabulek vzájemně odkazovaných, ze kterých mají být data načtena.

Způsob spojení tabulek, na základě příkazu uživatele.

Operace s daty, například filtrování, řazení nebo seskupování.
Exekuční plán je prováděn pro příkazy INSERT, DELETE, UPDATE nebo SELECT. (3)
Pro zobrazení exekučního plánu stačí před příkaz napsat „EXPLAIN PLAN FOR“.
Například:
EXPLAIN PLAN FOR SELECT last_name FROM customers;
Na následujícím obrázku je příklad exekučního plánu:
Obrázek 2: Exekuční plán
Zdroj: Vlastní zpracování
18
Z uvedeného exekučního plánu vyplývají následující operace. V prvním kroku jsou tabulky
spojeny, pak je použit full table access a z těchto dat je vybrána pouze určitá data podle
indexu ORD_CUSTOMER_IX.
V následující tabulce je uvedeno, jaké sloupce může exekuční plán obsahovat a jejich
stručný význam.
Tabulka 1: Popis sloupců exekučního plánu
Sloupeček
exekučního
Popis
plánu
Operation
Name
Prováděná operace v rámci jednoho kroku
exekučního plánu.
Odkaz na objekt, se kterým databáze v daném
kroku pracuje.
Rows
Počet řádek načtených v rámci daného kroku.
Bytes
Počet bytů načtených v rámci operace.
Relativní náročnost dané operace, velmi
Cost
užitečné pokud chceme hledat slabá místa
databáze.
CPU
Operation
Name
Očekávaná
náročnost
operace
z
pohledu
procesoru.
Prováděná operace v rámci jednoho kroku
exekučního plánu.
Odkaz na objekt, se kterým databáze v daném
kroku pracuje.
Rows
Počet řádek načtených v rámci daného kroku.
Bytes
Počet bytů načtených v rámci operace.
19
Exekuční plán je velmi komplexní popis operací prováděných databází. V příkladu a
popisu uvedeného exekučního plánu jsem uvedl nejzákladnější informace, abych alespoň
stručně nastínil jeho možnosti.
Díky exekučnímu plánu dokážeme analyzovat všechny provedené operace k danému
příkazu a dokážeme zjistit, která z operací je nejnáročnější, na tu se zaměřit a vyřešit dané
slabé místo databáze. Proto pokud děláme výkonnostní testy, jedním ze základních
nástrojů pro zjišťování průběhu je právě exekuční plán.
20
2.4. Indexy
Indexy jsou pomocné databázové objekty, které zrychlují přístup k tabulkám.
Nejjednodušší vysvětlení je na příkladu rejstříku knihy. Pokud čtenář hledá v knize pojem,
podívá se do rejstříku, než aby pročítal řádek po řádku celou knihu a hledal daný pojem.
Na úplně stejném principu fungují i indexy.
Indexy jsou také seřazeny a neobsahují odkaz na stránku, ale odkaz na rowid. Indexy nám
umožňují zrychlovat vyhledávání v tabulkách, ale bohužel na úkor vkládání, úprav a
mazání dat, protože nemanipulujeme pouze s daty, ale zároveň i s indexy. Indexy jsou
přiřazeny vždy k jednomu nebo více sloupcům a je důležité se zamýšlet, nad kterými
sloupci vytvoříme index. Pokud bychom vytvářeli indexy automaticky nad každým
sloupcem, vedlo by to ke zpomalení databáze, ne k jejímu zrychlení.
Indexy jsou logicky i fyzicky odděleny od dat tabulky, proto je možné je vytvářet nebo
mazat aniž bychom změnili data databáze. Pokud ale smažeme index, který databáze
používala k přístupu k datům, pak se prodlouží přístupová doba k těmto datům. Společnost
Oracle doporučuje vytvářet indexy nad primárními klíči tabulky a nad klíči, které odkazují
na jiné tabulky. Obecné doporučení zní, aby indexy byly vytvořeny nad těmi sloupci, které
často používáme pro prohledávání dat v tabulce. (4)
Je důležité si uvědomit, že i v případě, kdy máme index nad tabulkou vytvořený, nemusí se
využít pro přístup k datům. Proto bezhlavé přidávání indexů do tabulky není žádoucí.
2.4.1. B-Tree index
Tento typ indexu je nejčastějším typem a je doporučováno ho používat pro sloupce v
tabulce, které obsahují velký počet řádků a mají velkou kardinalitu dat (pojem kardinality
bude popsán níže). Ideální případ použití je u tabulky, která obsahuje velký počet řádků,
ale na základě dotazu do této tabulky je vybrán relativně malý počet dat. V takovém
případě je index efektivně využit. Nad tímto typem sloupců se doporučuje indexy vytvářet.
Pro který sloupec tabulky index použít?
Jednak pro sloupec, který je často používán pro prohledávání dat a jednak na základě
určení selektivnosti. Pojem „selektivnosti“ velmi úzce souvisí s pojmem „kardinality“.
21
Nejprve bude vysvětlen pojem „kardinality“. Ta určuje, jak různorodá data databáze
obsahuje. Typickým příkladem dat s nízkou kardinalitou je určení pohlaví, kde jsou pouhé
dva typy hodnot - muž a žena. Na druhou stranu typickým příkladem dat s vysokou
kardinalitou je unikátní primární klíč tabulky, který jednoznačně určuje jednotlivé řádky.
V takovém případě je kardinalita vysoká a počet řádek udává počet hodnot typů dat. Proto
se indexy nad primárními klíči vytváří v databázovém systému Oracle automaticky.
Pojem „selektivita“ udává procentuálně, kolik je vráceno dat pro jednu unikátní hodnotu
vzhledem k celkovému počtu dat v tabulce. Tedy čím je vyšší kardinalita – větší
rozrůznění dat, tím je menší selektivita – menší počet dat, které lze dostat pro jednu
hodnotu. (5) Nejlépe pojem „selektivity“ popíše definice:
selektivita=
počet unikátní hodnoty
celkový počet záznamů
Pokud toto pravidlo je použito na výše zmíněný příklad pohlaví a pokud je předpoklad
rozdělení mužů a žen 50 na 50, pak je pro muže i ženy selektivita 50 %. Pro takto vysokou
selektivitu rozhodně nelze doporučit vytvoření indexu. Druhým příkladem je unikátní
primární klíč, zde za předpokladu že tabulka obsahuje 100 řádků, pak selektivita vychází
na 1 %.
Obecně pokud má být vytvořen b-tree index, pak selektivita daného sloupce by měla být
maximálně 10 %.
Pro zjištění selektivity daného sloupce tabulky může být použit tento příkaz:
SELECT COUNT (DISTINCT first_name) / COUNT (first_name)
* 100 “selectivita” FROM emp;
V uvedeném příkladu je selektivita počítána na sloupci first_name tabulky emp.
Je patrné, že při generování dat je důležité zachovat pravděpodobnost výskytů jednotlivých
hodnot. Proto pokud jsou vygenerována data, kde jsou pouze 3 typy hodnot a navíc každá
hodnota má pravděpodobnost výskytu 1/3, žádný hodnověrný výkonnostní test s takovými
daty nelze provést.
22
Bylo vysvětleno, kdy je či není vhodné b-tree index použít. V následující kapitole bude
popsán způsob uložení b-tree indexu v databázi, který je důležitý pro pochopení nutnosti
přepočítávání indexů.
Jak název napovídá, tento index je založen na principu b-stromu. Tento typ datové
struktury se skládá z kořene (root), uzlů (node) a listů (leaf). Viz obrázek 3 níže.
Obrázek 3: B - tree index
kořen
122
uzly
65
136 151
listy
16 – Rowid
35 – Rowid
65 – Rowid
66 – Rowid
97 – Rowid
122 – Rowid
123 – Rowid
135 – Rowid
136 – Rowid
139 – Rowid
150 – Rowid
151 – Rowid
160 – Rowid
190 – Rowid
650 – Rowid
Zdroj: Vlastní zpracování Visio 2007 podle zdroje: http://www.dba-oracle.com/art_9i_indexing.htm
Jak kořen, tak uzly mohou obsahovat větší počet hodnot. Tyto hodnoty jsou seřazeny, a
pokud má kořen (uzel) n hodnot, pak má vazby na n+1 uzlů (listů). (Obrázek b-tree indexu
je trochu zjednodušený, b-tree index může obsahovat větší počet „vrstev“ uzlů.) Hodnoty v
dětech (podřízených uzlech/listech) mají stejnou nebo nižší hodnotu, pokud jsou vlevo a
vyšší hodnotu pokud jsou vpravo oproti svému předchůdci (uzlu/kořenu, ze kterého vazby
vycházejí). Na základě těchto pravidel se vytváří datová struktura b-strom. Výpočet
hloubky jednotlivých větví (počet zanoření od kořene k listu) je trochu složitější a není
předmětem této bakalářské práce. Jen pro úplnost doplním, že pro efektivní vyhledávání v
b-stromu je potřeba, aby hloubka stromu jednotlivých větví se vzájemně lišila maximálně o
1. Pokud tento rozdíl hloubky v jednotlivých větvích b-stromu je výrazně větší, pak je
potřeba indexy přepočítat.
Jednotlivé hodnoty se v b-stromu vyhledávají tak, že se strom postupně prochází od kořene
a porovnávají se jednotlivé hodnoty s hodnotou hledanou. V momentě kdy se dojde do
23
nejnižší části b-stromu do listů, tak se zde hledaná hodnota buďto nenachází nebo nachází
a v listě je odkaz na rowid řádku, kde je hodnota uložena.
Teď je možné si uvědomit, proč je neefektivní vytvářet b-tree index nad sloupci s nízkou
kardinalitou. Pokud by se nad sloupcem pohlaví vytvořil b-tree index, pak by v tomto bstromu byl pouze kořen a dva listy, viz obrázek 4. Každý z těchto listů by obsahoval
polovinu řádků tabulky, které by vraceli při zvolení dané hodnoty. Ve výsledku by tedy byl
zvolen nejprve přístup indexový a následně by byla data postupně procházena. V takovém
případě by bylo buď vhodnější nepoužít index žádný, pak by databáze k datům
přistupovala přes full table scan nebo by byl použít bitmap index (popsán v následující
kapitole). Tento příklad je pouze hypotetický, protože pokud by byl vytvořen index nad
těmito daty, optimizer by spočítal neefektivnost indexového přístupu a použil by rovnou
full table scan.
Obrázek 4: B - strom s nízkou kardinalitou
Pohlaví
Muž
Žena
Zdroj: Vlastní zpracování Visio 2007
B-tree indexy můžeme vytvářet různými způsoby. Jedním ze způsobů je kompozitní index.
Kompozitní index
Tento typ indexu se vztahuje ke dvěma sloupcům. Je vhodný pro případy, kdy často
používáme kombinaci dvou sloupců současně pro vyhledávání. Ale pozor, na druhou
stranu je mylné se domnívat, že pokud je zvolen kompozitní index, tak že může být použit
stejně, jako dva nezávislé indexy nad dvěma sloupci. Navíc při volbě sloupců záleží na
tom, v jakém pořadí je zvolíme. (6) Uvedu a popíšu příklad kompozitního indexu:
CREATE INDEX composite_index ON emp (surname,
first_name);
24
V tomto příkladě je vytvořen index, který je nad sloupci surname a first_name a pokud je
použit příkaz:
SELECT * FROM emp WHERE surname='Novak' AND
first_name='Jan';
je použit index tak, jak předpokládáno. V případě, že by bylo potřeba vyhledávat pouze
podle jména, například takto:
SELECT * FROM emp WHERE first_name='Jaroslav';
index nebude použit! Index nebo spíše jeho část se použije pouze v případě, kdy je v
tabulce vyhledáváno pouze podle příjmení. Kompozitní indexy se mohou skládat i z více
než dvou hodnot a to tak, aby tyto skupiny sloupců co nejvíce usnadňovaly vyhledávání.
Proto se doporučuje používat kompozitní indexy tak, aby sloupce v nich obsažené byly
řazeny sestupně podle důležitosti (četnosti použití).
Indexovaná funkce
Dalším způsobem jak vytvořit b-tree index je indexovaná funkce, která umožňuje vytvořit
index nad hodnotou vrácenou z funkce. Příklad:
CREATE INDEX function_index ON emp(lower(surname));
V tomto příkladě se vytváří index nad funkcí lower, díky které se zjednoduší vyhledávání
příjmení. Lze vynechat kontrolu, zda nebyla příjmení zadána s velkým písmenem. Ukázka
dotazu nad tabulkou:
SELECT first_name, surname FROM emp WHERE lower(surname)
= 'muller';
Obecně indexové funkce zjednodušují používání funkcí v rámci dotazů nad tabulkami.
Mohou se tak jednoduše třídit data, dále se nemusí řešit velká a malá písmena v zadaných
datech nebo se mohou přidat vlastní funkce, které zjednoduší zpracování dat.
Používání indexů má jeden háček, a tím je hledání řádků, které obsahují hodnotu null.
Pokud se zadá příkaz, který má vrátit všechny řádky, kde v některém ze sloupců je
25
podmínka null, vždy databáze k tabulce přistoupí přes full table scan. Tento háček lze
jednoduše řešit pomocí indexových funkcí. Tato funkce nahradí null hodnotu řetězcem
'null', následně jsou pak hledány v tabulce řetězce ‘null’. Předpokladem je, že se jedná o
proměnnou typu řetězec. U sloupců s jinými datovými typy by bylo řešení analogické.
Toto nahrazení můžeme provést pomocí funkce nvl, která vrací předdefinovanou hodnotu,
pokud jí nebyla předána žádná jiná hodnota. Ukázka použití pomocí index funkce:
CREATE INDEX indx_find ON emp(nvl(degree, 'null'));
Díky takto použité indexové funkci je možné za pomocí indexů najít uživatele, kteří
nedosáhli žádného titulu (degree). Příklad:
SELECT first_name, surname FROM emp WHERE nvl(degree,
'null') = 'null';
I když je vytvořen index nad sloupcem správným způsobem, nemusí být použit pro vrácení
dat. Databáze přístupy k datům vyhodnocuje a vrátí vždy data předpokládaným
nejefektivnější způsobem. Výběr nejefektivnějšího přístupu k datům obstarává optimizer
(popsán v samostatné kapitole). Proč databáze nevolí přístup přes b-tree indexy, i když se
to může zdát výhodné? Důvody:
1. Malé množství řádků – je rychlejší přistupovat k malému množství dat přes full
table scan než přes index scan
2. Velké množství řádků, ale načítání velkého množství dat – i v tomto případě je
výhodnější použít full table scan, protože FTS načítá data po blocích na rozdíl od
IRS, který načítá data sekvenčně
Ze zmíněných důvodů je zřejmé, že je důležité nejen volit indexy pro správné sloupce,
popřípadě kombinace sloupců, ale i správně psát dotazovací příkazy pro databázi. Dále je
velmi důležité nepodceňovat správu a údržbu databáze, díky které ji pak můžeme snadněji
optimalizovat nebo odstraňovat vzniklé problémy.
2.4.2. Bitmap index
Dalším typem indexu je bitmap index. Tento typ indexu je stejně jako b-tree index uložen
v b-stromu. Tento index je vhodný pro tyto typy dat:
26

Data s nízkou kardinalitou.

Data, kde převládají read-only operace nebo úpravy dat jsou jen výjimečné.

Data, kde často vyhledáváme pomocí OR podmínek.
Jak bylo uvedeno, bitmapové indexy jsou uloženy také v b-stromu. To zaručuje rychlé
vyhledávání jednotlivých hodnot. V čem je ale tento index od b-tree indexu odlišný, je
způsob uložení hodnot v listech b-stromu. V listu je uložena bitmapa hodnot místo
seznamu rowid. Tato bitmapa se vztahuje k zadanému rozsahu řádků, které jsou uloženy v
paměti. V bitmapě má nastavený bit na „1“ ten řádek, který zadanou hodnotu obsahuje a
„0“ ten řádek, který zadanou hodnotu neobsahuje. Princip bitmap indexu viz Obrázek 5.
Obrázek 5: Bitmap index
Zdroj: http://www.siue.edu/~dbock/cmis565/module12-indexes.htm
Vysvětlení principu tohoto indexu bude nejjednodušší na příkladu. Snažíme se najít
všechny muže v naší firmě. Průchod b-stromem bude rychlý, jsou v něm pouze dva listy. V
listu s hodnotou „muže“ bude bitmapa mapující hodnoty v paměti a bude obsahovat
jedničky tam, kde se hodnota muž nachází a nuly, kde se nenachází. Bitmapa nám vrátí
sadu řádek, které obsahují hledanou hodnotu. Jak tento index vypadá, je možno se podívat
27
na obrázku níže, kde je podrobně rozkreslen. Díky tomuto nízko úrovňovému přístupu k
datům (přístup přes bitmapu) je načítání dat rychlejší. Způsob uložení a pracování s
bitmapou je speciálně navržen společností Oracle a patentově chráněn. (4)
Jediným háčkem bitmapových indexů je jejich případná úprava. Sice není tak velký
problém data měnit z jedné hodnoty na jinou. To znamená pouhou změnu bitů z nuly na
jedničku. Ale pokud bude potřeba přidat novou hodnotu do sloupce, pak se musí přepočítat
úplně celá indexová struktura. To není jednoduchá operace. Z tohoto vyplývá nemožnost
použití těchto indexů v OLTP databázích, které jsou zaměřeny na snadnou modifikaci dat.
2.4.3. Indexově organizované tabulky (Index organized tables)
Indexově organizovaná tabulka se vzdáleně týká indexů a jedná se o speciální strukturu
dat, kam se ukládá tabulka. Ale na základě principu indexů byla vyvinuta.
Tento typ tabulky vznikl na základě těchto myšlenek:

Je neefektivní vytvářet index nad každým sloupcem tabulky

Zároveň byl využit koncept FFIS (Fast full index scan), kdy přístup přes indexy k
datům je velmi rychlý.
Tak vznikl koncept index organized table, kdy řádky tabulky nejsou uspořádány podle
rowid, ale jsou vloženy do b-stromu, kde jsou uspořádány podle primárních klíčů. Zároveň
v každém listě jsou uloženy i neklíčové hodnoty řádku, proto přes primární klíč
přistupujeme rovnou ke všem hodnotám. To zaručuje velmi rychlý a efektivní přístup.
Bohužel tento koncept má i nějaké nedostatky. Například tento typ tabulek nelze ukládat
do clusterů. (4)
Pokud by se měřila rychlost přístupů, mohlo by být na první pohled zarážející, že tabulky s
indexy oproti index organized table nejsou zas o tolik pomalejší. Pak by jejich jedinou
praktickou výhodou byla úspora místa. Protože indexově organizovaným tabulkám stačí
ukládat jedinou strukturu dat oproti ukládání samotných dat a navíc jejich indexů. Ovšem
index organized table lze dále optimalizovat, a to následujícími způsoby:
28

Dodefinováním overflow area (oblast přetečení), díky které je v listě uloženo jen
omezené množství dat a data, která se do listu nevejdou, jsou uložena na jiném
místě.

Přidáním sekundárních indexů, které nám dále zrychlují přístup k datům.
Využití tohoto typu tabulek je doporučováno pouze pro kratší řádky, kde v jednotlivých
řádcích není uloženo větší množství dat. Částečně lze toto optimalizovat pomocí overflow
area, ale i přesto je lepší používat tyto tabulky spíše pro ukládání krátkých řádků. Dalším
omezením je nemožnost ukládat datové proměnné typu long, místo něj musíte použít
datový typ lob. (7)
29
2.5. Optimizer
Aby byla jasná úloha optimizeru v rámci zpracování sql příkazu, bude nejprve popsán
obecný popis komponent, které s optimizerem souvisí.
Nejprve uživatel zadá sql dotaz, ten je zkontrolován parserem z hlediska korektnosti
syntaxe, zda dotaz obsahuje všechny povinné položky a zda mají korektní formu. Pak
přichází na řadu optimizer, který vybere způsob optimalizace vykonání dotazu na základě
toho, zda existují statistiky nebo ne. Pokud statistiky vygenerovány v databázi jsou,
použije se výpočet optimální cesty pomocí CBO (Cost-Based Optimizer) přes statistiky.
Pokud ne, CBO použije dynamic sampling pro dopočítání chybějících nebo neúplných
statistik. V případě požadavku na zpětnou kompatibilitu může být zvolen i druhý typ
optimizeru – RBO (Rule Based Optimizer). (8)
Obrázek 6: Diagram zpracování sql dotazu
Zdroj: http://docs.Oracle.com/cd/B10501_01/server.920/a96533/optimops.htm
30
Optimizer vrací návrh nejefektivnějšího způsobu jak načíst data z databáze. Následující
komponenta Row Source Generator na základě tohoto vygenerovaného postupu vrací
exekuční plán. Exekuční plán popisuje podrobně načítání a zpracování dat. Posledním
logickým krokem je vykonání příkazu podle exekučního plánu pomocí SQL Execution
Engine („stroje pro vykonání sql“). Postupné kroky tohoto procesu je možné si
prohlédnout na obrázku 6 diagramu zpracování sql dotazu.
Databáze může volit různé přístupy k tabulkám. Může být zvolen přístup full table scan
nebo některý z indexových přístupů. Optimizer volí na základě znalosti tabulek z těchto
přístupů ten nejefektivnější. V jeho konfiguraci můžeme zvolit jeden ze dvou modů cílů
optimalizace. A to buď nejlepší propustnost (the best throughput) nebo nejlepší dobu
odezvy (the best response time). Na příkladech bude vysvětlen rozdíl těchto dvou modů.
(9)
Pokud zvolíme nejlepší propustnost, optimizer volí takové přístupy, aby všechna data
dostal uživatel co nejdříve. Tento model je volen tehdy, kdy uživatel požaduje ihned načíst
všechna data z databáze v nejkratším možném intervalu. Typickým a často voleným
přístupem v tomto modu je full table scan, který dokáže data načítat po blocích, a tím
načíst velmi rychle velké množství dat.
Druhý mode (nejlepší doba odezvy) je volen tehdy, kdy uživatel systému chce mít k
dispozici co nejdříve první řádek nebo prvních pár řádků. Typickým přístupem, který je
volen v tomto modu, je index scan. Tento přístup je schopen velmi rychle vrátit první
požadovaný řádek.
Z řádků napsaných výše by mohlo vyplývat, že přístup full table scan je výhradně volen v
modu optimizeru „nejlepší propustnost“ a index scan v modu „nejlepší doba odezvy“.
Takto přístupy voleny nejsou. Optimizer má nastaveny určité preference, díky kterým volí
jednotlivé přístupy, ale rozhodně nejsou v jednotlivých modech voleny pouze některé
přístupy, to by databázový přístup k datům nebyl dostatečně flexibilní a optimalizovatelný.
2.5.1. RBO (Rule based optimizer) a CBO (Cost based optimizer)
Jak bylo zmíněno výše, Rule based optimizer je volen z důvodu požadavku zpětné
kompatibility. Naproti tomu Cost based optimizer je novější a technologicky vyspělejší. I
společnost Oracle doporučuje používat CBO. RBO by měl být použit pouze ve
31
výjimečných případech a můžeme očekávat, že v budoucích verzích bude z databáze
odstraněn. Navíc Cost based optimizer podporuje rozdělené tabulky, materializované
pohledy a další.
Krátce k Rule based optimizeru:
Tento typ optimizeru je založen na pravidlech. Jednotlivé přístupy jsou vybírány podle
pořadí, a zda je možné je nad tabulkou vykonat. Tedy pokud je možné zvolit více přístupů,
je zvolen ten, který je v pořadí dříve. Část seřazeného seznamu přístupů, tak jak jej využívá
RBO:
Tabulka 2: Pořadí přístupů, které jsou voleny v RBO
Pořadí
Přístup
1.
Jednotlivé řádky přes Rowid
...
Jednotlivé řádky přes
4.
unikátní hodnotu nebo
primární klíč
...
8.
Přes kompozitní indexy
9.
Indexový přístup
...
15.
Přes full table scan
Z tabulky je tedy patrné, že pokud bude možné zvolit přístup přes index, bude vždy zvolen,
a to i v případě, kdy by byl přístup přes full table scan efektivnější. Proto je doporučováno
tento typ optimalizátoru nepoužívat. (10)
32
Cost based optimizer je založen na ohodnocování jednotlivých přístupů do databáze na
základě statistik tabulek, sloupců, indexů a dalších (statistiky popsány v samostatné
kapitole). Na základě hodnot těchto statistik CBO navrhne exekuční plány a zároveň je
ohodnotí. Databáze pak z plánů vybere ten nejvýhodnější, který je proveden pro
zpracování zadaného příkazu. Součástí hodnocení statistik není jen složitost datové
struktury databáze, ale i možnosti jednotlivých zdrojů hardwaru serveru, například
propustnost I/O nebo výkonnost CPU. (8)
Samotný CBO se skládá z několika částí, které si vzájemně dělí jednotlivé činnosti
zpracování hodnocení přístupů. Popis těchto částí je však nad rozsah této práce.
33
2.6. Statistiky
Statistiky jsou pomocná data, která podrobně popisují strukturu databáze. Popisují tabulky,
sloupce, indexy atd. Na základě těchto dat, je pak optimizer (konkrétně CBO) schopen
najít nejefektivnější exekuční plán.
Statistiky popisují různé objekty v databázi a podle toho se dělí na:

statistiky tabulek (table statistics),

statistiky sloupců (column statistics),

statistiky indexů (index statistics),

statistiky výpočetních možností serveru (System statistics).
Ke spravování statistik se používá balíček DBMS_STATS. Tento balíček neslouží jen ke
sběru statistik, ale také k importu, exportu popřípadě i jejich smazání nebo zamknutí, pro
nemožnost jejich úpravy. Jednoduchý export nebo import statistik je umožněn díky tomu,
že statistiky jsou uloženy v databázových slovnících (11).
Je zřejmé, že data se v databázi často mění a pokud by jednou vygenerované statistiky
měly být používány delší dobu, ztratila by se jejich schopnost optimalizovatelnosti. Proto
je důležitá jejich pravidelná správa. O tu nejzákladnější se stará automatic optimizer
statistics collection. Tato funkcionalita se aktivuje následujícím příkazem:
EXECUTE DBMS_AUTO_TASK_ADMIN.ENABLE(
client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL);
Tato komponenta monitoruje počet operací INSERT, UPDATE, DELETE a pokud je
vyhodnoceno, že statistiky již neodpovídají datům, jsou přepočítány. Většinou se statistiky
přepočítávají, pokud se změní víc jak 10 % dat v tabulce.
Tato automatická detekce je postačující, pokud není databáze z velké části neustále
modifikována. Pokud ano, je pak důležité statistiky aktualizovat navíc manuálně. Manuální
sběr statistik je nutný v případě, kdy třeba změníme podstatnou část tabulky pomocí bulk
operací. (Pojem bulk operace je vysvětlen v kapitole 3.1. Úvod do PL/SQL.) Proto je nutné
34
při těchto operacích nezapomínat na statistiky. Vynucení přepočítání statistik způsobí
následující příkaz:
EXECUTE
DBMS_STATS.GATHER_TABLE_STATS(ownname=>tableowner,
tabname=>'tablename', method_opt=>'FOR ALL INDEXED
COLUMNS');
Na základě tohoto příkazu jsou přepočítány statistiky nad tabulkou „tablename“
vlastněnou uživatelem „tableowner“. Statistická data jsou posbírána ze všech jejích
sloupců. Tento příkaz patří do skupiny statistiky tabulek. V příkladu je volána metoda
GATHER_TABLE_STATS.
Pokud
by
byla
použita
jiná
procedura
balíčku
DBMS_STATS, například procedura GATHER_SYSTEM_STATS, pak by došlo
k vygenerování systémových statistik. U této procedury by samozřejmě byly nastaveny
jiné parametry (11).
V ukázkových příkladech byl vždy použit balíček dbms_stats, který ale není jediný, který
můžeme pro práci se statistikami volat. Ale jeho používání je doporučováno společností
Oracle. Kromě tohoto balíčku lze například použít příkaz ANALYZE, který je
v databázovém systému udržován již jen z důvodů zpětné kompatibility.
Na konci této kapitoly jsou zmíněny funkcionality, které se statistikami souvisí už jen
okrajově, ale jsou důležité pro pochopení souvislostí. Jedná se o dynamic sampling a
histogramy.
Dynamic sampling
Tato funkcionalita byla zavedena od verze 10g a vyřešila velký problém optimalizace pro
tabulky, kde nejsou vygenerované statistiky. Do této verze v takovém případě byl použit
RBO, který nemusel vrátit optimální exekuční plán.
Dynamic sampling umožňuje dopočítat chybějící data statistik a poskytnout tak v každém
případě co možná nejvíce optimální exekuční plán. CBO se během každé kompilace
dotazu rozhoduje, do jakého stupně použije dynamic sampling. Toto rozhodování je
založeno na mnoho faktorech. Ale hlavním důvodem proč optimizer volí tuto metodu, jsou
zastaralé nebo chybějící statistiky. (8)
35
Histogramy
Histogramy jsou speciálním druhem statistik a jsou zde uvedeny pro úplné doplnění výčtu.
Histogramy jsou důležité pro případy, kdy potřebujeme zjistit přesnější rozmístění dat v
databázi. Tento typ statistik nám dává přehled, jak jsou data asymetricky rozložena a na
základě těchto dat se optimizer rozhoduje, který přístup zvolí.
36
2.7. Hinty
Hinty nám umožňují ovlivňovat běh exekučního plánu. Je možné tak databázi nadefinovat,
který přístup má zvolit. Vychází z předpokladu, že uživatel má více informací o databázi
než optimizer, proto může zvolit efektivnější přístup. Například máte podrobnější
informace o selektivnosti indexů pro určitý SQL příkaz.
Hinty mohou být vyvolány jen v případě, kdy používáte CBO a pokud je zadáte v příkazu
ve špatném formátu, pak budou ignorovány a neprovedou se. Pozor, optimizer
neupozorňuje na to, že nebyly použity. Hinty se zadávají do SQL příkazů za příkazy
UPDATE, SELECT nebo DELETE. Přes hinty lze ovlivnit:

Přístup k tabulkám.

Jakým způsobem se mají tabulky spojit.

Určit pořadí spojení tabulek.

Nastavení optimalizačních parametrů.
Příklad použití hintu:
SELECT /*+ FULL(users) */ firstname, surname FROM users
WHERE firstname = 'Hana';
O tabulce users víme, že obsahuje velký počet uživatelů s křestním jménem „Hana“, proto
pomocí hintu optimizer nastavíme tak, aby k této tabulce přistoupil přes FTS, který v tomto
konkrétním případě bude nejrychlejší. (12)
37
3.
PRAKTICKÁ ČÁST - GENEROVÁNÍ DAT
Praktická část bakalářské práce se zaměřuje na samotný popis „Nástroje na tvorbu
testovacích dat pro zátěžové testování DB“. V této části bude popsán jazyk PL/SQL, ve
kterém je nástroj napsán. Dále zde je zmíněno, odkud byla získána zdrojová data a jak byla
upravena. A v neposlední řadě bude rozebrán princip, jakým nástroj generuje náhodná data
pro zátěžové testy. Vysvětlení principů je doplněno o ukázky zdrojového kódu nástroje.
3.1. Úvod do PL/SQL
V kapitole „Relační databáze“ byl zmíněn jazyk SQL a skupiny příkazů, které obsahuje.
Díky tomuto jazyku je možné navrhnout i spravovat databáze. Pokročilejší programování
nebo práce s větším množstvím dat ale není možná. Pro tyto případy společnost Oracle
vyvinula procedurální nadstavbu jazyka SQL, PL/SQL. Jiné databázové technologie mají
také své procedurální jazyky, například Microsoft SQL server má Transact SQL neboli
T-SQL. (13)
Tento krátký úvod se zaměřuje na základy programovacího jazyka PL/SQL, které jsou
nutné pro následné pochopení principu generátoru dat pro zátěžové testy.
3.1.1.
Balíčky, procedury a funkce
Program v PL/SQL je složen z bloků, které mohou být vnořeny jeden do druhého. Každý
blok spouští jednu logickou akci v programu. Blok se skládá z následujících částí:
a) DECLARE – v této části bloku jsou definovány jednotlivé proměnné a jejich
datové typy
b) BEGIN – výkonná sekce – v této části se vykonávají funkce, procedury a SQL
příkazy (tato jediná část je v bloku povinná)
c) EXCEPTION – v této části se zpracovávají výjimky, ke kterým došlo ve
výkonné části
Ve výkonné části je povolena skupina příkazů DML, to znamená SELECT, INSERT,
38
UPDATE, DELETE a další příkazy pro správu transakcí. Příkazy pro definování struktury
databáze (příkazy DDL) například CREATE, ALTER nejsou ve výkonném bloku
povoleny. (14)
Tímto způsobem jsou definovány tak zvané anonymní bloky, které jsou zpravidla
vykonány pouze jedenkrát. Dalším typem bloků jsou pojmenované bloky. Pojmenované
bloky je možné opakovaně používat a tyto bloky jsou procedurami a funkcemi, které jsou
známy ze strukturovaného programování. Jen pro zpřesnění: rozdíl mezi funkcí a
procedurou je ten, že funkce na rozdíl od procedury vrací výsledek. V dalším textu jsou
zmiňovány jen funkce, ale jsou tím míněny funkce i procedury. (15)
Příklad jedné funkce z praktické části práce:
CREATE OR REPLACE FUNCTION my_divide (n1 IN number, n2
IN number) RETURN NUMBER IS
n3 NUMBER;
n4 NUMBER;
BEGIN
n4 := MOD(n1,n2);
n3 := (n1-n4)/n2;
IF n4 > 0 THEN
n3 := n3+1;
END IF;
RETURN n3;
EXCEPTION
WHEN ZERO_DIVIDE THEN
RETURN n1;
END;
V praktické části práce byla potřeba funkce, která by dělila dvě čísla tak, aby vrácený
výsledek byl vždy zaokrouhlen nahoru. Standardní funkce pro dělení výsledek automaticky
zaokrouhluje nahoru nebo dolů, podle hodnoty za desetinnou čárkou.
Funkce my_divide převezme dva parametry n1 a n2. Nejprve zjistí celočíselný zbytek po
dělení n1, n2. Tento zbytek je poté odečten od n1 a upravená hodnota n1 je dělena
hodnotou n2, pokud byl celočíselný zbytek větší než jedna, je k výsledku přičtená jednička.
39
Tento příklad obsahuje všechny možné části, které byly pro blok definovány, a je na něm
vidět způsob použití jednotlivých bloků. Další výhodou definovaných funkcí je možnost
jejich použití přímo v SQL příkazech. Například:
SELECT CONCAT (first_name, surname) ‘whole name’ FROM
employees;
Tento příkaz vrátí místo dvou sloupců jména a příjmení sloupec jeden, který obsahuje celé
jméno. Jiným způsobem je použití funkcí v rámci indexů. Příklady, jak použít funkce
v indexech, byly popsány v kapitole „Indexovaná funkce.“
Bylo popsáno, jak vypadají anonymní a pojmenované bloky používané v programovacím
jazyce PL/SQL. Pokud by byly používány buď jen funkce, nebo dokonce pouze anonymní
bloky, bylo by náročné se v kódu vyznat. Proto jsou v tomto jazyce zavedeny balíčky,
které obsahují logicky související funkce a procedury.
Balíčky se skládají z hlavičky a těla. V hlavičce se deklarují veřejné funkce a v těle jsou
pak definovány funkce soukromé. Soukromé funkce jsou deklarované i definované v
jeho těle a nejsou přístupné z vnějšku. Veřejné funkce pak mohou být volány uživatelem
nebo funkcemi i z jiného balíčku. Příklad jednoduché definice hlavičky a těla:
CREATE PACKAGE my_package IS
FUNCTION sum (number1 NUMBER, number2 NUMBER,
number3 NUMBER);
END my_package;
CREATE PACKAGE BODY my_package IS
FUNCTION sum (number1 NUMBER, number2 NUMBER,
number3 NUMBER)
IS
BEGIN
RETURN number1 + number2 + number3;
END;
END my_package;
40
Uvedený balíček obsahuje jedinou veřejnou funkci, která slouží pro sečtení tří čísel. Tento
balíček neobsahuje žádnou soukromou funkci. Tento příklad je pouze názorný, a pokud by
měla být v balíčku pouze jedna veřejná funkce, nemělo by význam balíček zakládat.
Generátor náhodných dat, který je předmětem této bakalářské práce, je napsán pomocí
funkcí, které jsou vloženy do balíčků. Jejich přehled:
1. fetch_source_data_package – balíček sloužící k načtení zdrojových dat, na základě
kterých se generují náhodná data,
2. log_package – balíček sloužící k logování událostí vzniklých během procesu
generování dat,
3. random_data_package – balíček ke generování specifických dat, která mají
specifické omezující parametry (například generování rodného čísla),
4. random_table_package – balíček, který slouží k vytvoření tabulky a následnému
jejímu naplnění generovanými daty, tento balíček je stěžejním a jednotlivé funkce a
procedury z ostatních balíčků jsou volány odsud.
Pro zrychlení operací s velkým množstvím dat nabízí PL/SQL bulk operace. Tyto operace
snižují počet přepínání mezi enginem pro SQL a enginem pro PL/SQL. Jednotlivé enginy
slouží k vykonávání buď SQL nebo PL/SQL kódu. Princip přepínání enginů viz obrázek 7.
Obrázek 7: PL/SQL a SQL engine
Zdroj: http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/overview.htm
41
Pro snadnější pochopení významu bulk operací bude vysvětlen jejich princip zpracování
příkazů na příkladu cyklu. V každé iteraci cyklu je vložen jeden řádek do tabulky pomocí
příkazu INSERT, dochází tak k neustálému přepínání mezi enginy. Bulk operace v tomto
případě nejdříve nahromadí data pro vložení a následně je všechna vloží, proto je
provedení pomocí bulk operací mnohonásobně rychlejší. V praktické části jsou používány
bulk operace pro zefektivnění nástroje a optimalizované generování dat.
Toto byl krátký úvod do programování v jazyce PL/SQL, který má sloužit pro usnadnění
orientace v praktické části bakalářské práce. V následující kapitole již bude popsán
samotný kód „Nástroje pro generování dat pro zátěžové testy relačních databází“. (15)
42
3.2. Princip generování
Před samotným vysvětlením principu generování dat bude popsáno, jak byla získána a
zpracována zdrojová data, pomocí kterých se výsledná data generují. Bez těchto
zdrojových dat by nebylo možné generovat tak, aby vygenerované tabulky odpovídaly
realitě.
Zdrojová data pro generování
3.2.1.
Data byla získána ze stránek Ministerstva vnitra České republiky.
Tabulka 3: Internetové stránky, ze kterých byla získána zdrojová data
Internetová stránka
Data
www.mvcr.cz/clanek/cetnost-jmen-a-
Četnosti jmen, příjmení a roků narození,
prijmeni-722752.aspx
počet obyvatel ve městech
http://aplikace.mvcr.cz/adresa/xml.html Adresy v ČR
Data byla po stažení převedena do formátu csv. Ze zdrojových dat byly vytvořeny tyto
soubory:

mesta.csv – seznam měst ČR s počty obyvatel,

roky_narozeni.csv – rozdělení počtu obyvatel ČR podle roku narození,

zrjs_jmena.csv – počty obyvatel s křestními jmény v ČR,

zrps_prijmeni.csv – počty obyvatel s příjmeními v ČR,

…
V těchto souborech byla ponechána pouze data, která jsou použita pro samotné generování,
ostatní informace byly smazány. Například v souboru „mesta.csv“ jsou pouze dva sloupce,
a to názvy všech měst a jejich počty obyvatel. Podobné jsou struktury i ostatních souborů.
Všechny soubory se zdrojovými daty jsou součástí přílohy.
Upravené soubory se zdrojovými daty jsou postupně importovány do tabulky
„basic_source“. Tato tabulka je velmi jednoduchá, obsahuje pouze tři sloupce. Sloupec pro
klíčové hodnoty (názvy měst, křestní jména atd.), sloupec pro četnosti jednotlivých hodnot
43
a sloupec pro typ pohlaví pro rozlišení jmen mužských a ženských.
Jednotlivé soubory dat (města, příjmení atd.) jsou dále přesunuty z tabulky „basic_source“
do tabulky source_data, o který se stará procedura migrate_data. Při tomto převodu dat se
v tabulce source_data k jednotlivým datům každé skupiny vloží jejich typ. Hodnota tohoto
typu dat je předána proceduře vstupním parametrem, která ji vkládá do sloupce type_data.
Pojem typ dat je dále často v textu používán a jsou jím míněna tato data:

příjmení,

křestní jména,

města,

předvolby mobilních čísel,

roky narození.
Sloupec type_data je používán při každém generování dat pro získání jednoho typu dat,
proto je důležité nad tímto sloupcem vytvořit index. B-tree index v tomto případě není
úplně vhodný pro nízkou kardinalitu dat, jejíž hodnota je pouze pět. Pro tento sloupec se
výborně hodí index bitmapový, jednak proto, že data mají nízkou kardinalitu a jednak
proto, že předpokládáme nízkou frekvenci změn těchto dat. Díky tomuto indexu je načítání
dat z tabulek rychlejší. Jak toto načítání dat funguje, bylo zmíněno v odstavci o indexech.
S tabulkou source_data pracuje balíček fetch_source_data, který je popsán v následující
kapitole. Jen pro úplnost zmíním na závěr této kapitoly tři tabulky, které jsou také
používány jako zdroje dat. Jedná se o tyto tabulky: towns, streets a house_numbers,
v nichž jsou uloženy adresy až na úroveň popisných čísel domů a jsou používány pro
generování reálných adres ČR.
3.2.2.
Balíček fetch_source_data
Balíček fetch_source_data obsahuje funkce, které načítají zdrojová data do kompozitní
proměnné, kterou funkce vrací. V této datové struktuře nejsou již data uložena s četnostmi,
ale hodnoty jednoho typu dat jsou v tabulce uloženy několikrát, a to v závislosti na
četnostech, které jsou navíc děleny. Díky dělení četností je omezen rozsah dat. Dělitel
četností je odhadován na základě množství dat daného typu a jejich četností.
44
Následující zdrojový kód je jednou z implementovaných funkcí balíčku fetch_source_data:
function source_for_random (source_type in varchar2,
divide in NUMBER) RETURN type_random IS
CURSOR cursor_c(data_type varchar2) IS
SELECT * FROM source_data WHERE type_data =
source_type;
j number(10,0);
repetition number(10,0);
random_data type_random;
BEGIN
random_data := type_random();
-- external loop for retrieving the individual values
-- of one data type
FOR data_record IN cursor_c(source_type) LOOP
j := random_data.count;
repetition := data_record.count_data/divide;
random_data.extend(repetition);
-- inner loop for inserting a single value based on
-- its frequency
FOR i IN 1..repetition LOOP
random_data(suma(j,i)) := data_record.data1;
END LOOP;
END LOOP;
RETURN random_data;
END source_for_random;
Funkce přijímá jediný parametr, který je určen pro identifikaci typu dat, která mají být
načtena z databáze.
Funkci tohoto balíčku využívá balíček package_random_table, který pomocí funkce
source_for_random inicializuje své proměnné, v kterých jsou hodnoty jednotlivých typů
45
dat určené pro konečné generování. Než přejdeme k balíčku package_random_table, bude
popsán ještě jiný balíček, který slouží pro generování dat se specifickými vlastnostmi.
3.2.3.
Balíček random_data
Tento balíček slouží pro generování rodných čísel a celých adres. Tato data nelze pouze
vytáhnout z předpřipravených dat, ale je potřeba nejprve část dat vygenerovat a následně je
dopočítat podle omezujících podmínek.
Generování rodných čísel
Rodné číslo se skládá z deseti čísel, kde prvních šest označuje den narození a další čtyři
jsou přidělována jednotlivým porodnicím. Toto desetimístné číslo musí být navíc dělitelné
jedenácti. Pomocí rodného čísla lze rozlišit muže a ženu. Žena v rodném čísle má k měsíci
narození přičteno číslo padesát. Všechny tyto podmínky funkce pro generování rodných
čísel splňuje.
Generování rodných čísel funguje na tomto principu: Funkce dostane parametrem rok
narození a pohlaví generované osoby. Z těchto parametrů generuje náhodný den v roce,
kde zohledňuje přestupné roky a následně dopočítá rodné číslo tak, aby bylo dělitelné
jedenácti. Toto vygenerované rodné číslo je funkcí vráceno.
Roky narození, které jsou předávány funkci jako parametr, jsou generovány podle četností
věkových skupin obyvatel ČR, proto rozdělení věkových skupin vygenerovaných dat
odpovídá reálnému rozdělení věkových skupin obyvatel ČR.
Následující ukázka kódu je vyňata z funkce pro generování rodných čísel a je ukázkou
funkce, která generuje poslední čtyřčíslí tak, aby rodné číslo bylo dělitelné jedenácti.
LOOP
b_number_end := dbms_random.value(1,999);
birth_number := b_year * 10000000 + b_month * 100000 +
b_day * 1000 + b_number_end;
divide_modulo := mod(birth_number,11);
IF divide_modulo != 10 then
46
birth_number := birth_number * 10 + divide_modulo;
exit;
END IF;
END LOOP;
Kód předcházející ukázanou část obstarává vygenerování reálného data.
Generování adres
Funkce generuje kompletní adresu, jediným jejím vstupním parametrem je město. Tomuto
městu je náhodně vygenerována jedna existující ulice tohoto města a jedno existující číslo
popisné, které reálně existuje v dané ulici. Města předávaná funkci jsou generována na
základě počtu obyvatel jednotlivých měst ČR. Vygenerované adresy jsou proto reálné a
existují na území ČR. Ve vygenerovaných datech tedy logicky budou nejčastěji adresy
Prahy, kde žije nejvíce obyvatel.
Generování adres má drobný nedostatek, který je zapříčiněn odchylkou od reálných adres.
Ze zdrojových dat Ministerstva vnitra ČR nelze zjistit četnosti obyvatel v daných ulicích a
domech označených číslem popisným, proto zde jsou možné nesoulady. Je možné, že
některý reálný malý rodinný dům je považován za panelový dům a obráceně. Přesto
generování celých adres je velmi věrné realitě. Drobný nesoulad je dán omezeností
zjistitelných údajů a vůbec ničemu nevadí.
Tyto jednotlivé funkce, které vracejí pouze určitá vygenerovaná data, jsou volána hlavním
balíčkem package_random_table, který generuje samotnou tabulku a náhodná data. Tento
stěžejní balíček bude popsán v následujícím odstavci.
3.2.4.
Balíček package_random_table
Tento balíček je stěžejní a jeho funkce je volána pro vytvoření tabulky a vygenerování
potřebných dat. Tato operace je spuštěna tímto příkazem:
EXECUTE
package_random_table.generate(100000,'user_list');
Takto je vytvořena tabulka s názvem „user_list“, do které je vloženo sto tisíc řádků
47
náhodných dat.
Při spuštění příkazu z tohoto balíčku dojde nejprve k jeho inicializaci, v rámci které se
volají funkce, které nahrávají jednotlivá zdrojová data do kompozitních proměnných.
Balíček těchto funkcí byl vysvětlen v kapitole „3.2.2. Balíček fetch_source_data“. Ukázka
části inicializace:
random_surnames_women :=
fetch_source_data.source_for_random('surname',50,'Z');
random_first_names :=
fetch_source_data.source_for_random('first_name',100);
Podobným způsobem jsou inicializovány i proměnné pro ostatní typy dat.
Po inicializaci je spuštěna volaná funkce generate. V její deklarační části jsou definovány
kompozitní proměnné, kam se ukládají jednotlivé vygenerované hodnoty a další pomocné
proměnné. Je zde také možné nastavit parametr, který určuje, kolik dat se vloží do tabulky
v jednom cyklu. Implicitně je nastaven jeden tisíc řádek pro jeden cyklus. Prvním
příkazem spuštěným v sekci výkonného bloku je funkce pro vytvoření tabulky. Tato
funkce je soukromou funkcí balíčku package_random_table. Vytvořená tabulka je nazvána
podle předaného parametru funkci generate. Následně může začít generování náhodných
dat.
Data jsou generována a vkládána do nové tabulky v jednotlivých cyklech. Počet cyklů je
určen na základě požadavků na počet generovaných řádků v tabulce. V rámci jednoho
cyklu je vygenerován určitý počet dat (implicitně nastaveno na tisíc) a následně jsou tato
data vložena do nové tabulky. Vkládání dat probíhá pomocí bulk operací a kvůli těmto
operacím je generování a vkládání rozděleno na cykly tak, aby se data jednoho cyklu vešla
do operační paměti a nedošlo ke swapování na pevný disk. Pokud by k tomu došlo, celý
proces generování by byl velmi zpomalen.
Pro generování jednotlivých řádků volaných během každé iterace je implementována další
soukromá procedura, generate_row. Tato procedura generuje jeden řádek. Z ní jsou volány
další funkce pro generování všech dat daného řádku. Zdrojový kód této funkce:
procedure generate_row (sur OUT VARCHAR2, fir OUT
48
VARCHAR2, b_number OUT NUMBER, mob_number OUT NUMBER,
town OUT VARCHAR2, street OUT VARCHAR2, house_number OUT
NUMBER) IS
index_f_name PLS_INTEGER;
index_surname PLS_INTEGER;
index_birth_year PLS_INTEGER;
index_mobile_part PLS_INTEGER;
index_address_town PLS_INTEGER;
type_s VARCHAR2(1);
BEGIN
-- generating first name
index_f_name :=
dbms_random.value(1,random_first_names.COUNT);
fir := random_first_names(index_f_name);
SELECT type_sex INTO type_s FROM source_data WHERE
type_data='first_name' AND data1=fir;
-- generating surname
IF type_s = 'Z' THEN
index_surname :=
dbms_random.value(1,random_surnames_women.count);
sur := random_surnames_women(index_surname);
ELSE
index_surname :=
dbms_random.value(1,random_surnames_men.COUNT);
sur := random_surnames_men(index_surname);
END IF;
-- generating year of birth
index_birth_year :=
dbms_random.value(1,random_birth_year.COUNT);
b_number :=
random_data.generate_birth_number(random_birth_year(inde
x_birth_year),type_s);
-- generating mobile number
index_mobile_part :=
dbms_random.value(1,random_part_mob_number.COUNT);
mob_number :=
random_part_mob_number(index_mobile_part) * 1000000 +
dbms_random.value(100000,999999);
49
-- generating address
index_address_town :=
dbms_random.value(1,random_town.count);
town := random_town(index_address_town);
random_data.generate_whole_address(town, street,
house_number);
END;
Z procedury „generate_row“ jsou volány funkce pro generování rodného čísla a adres
zmiňované v kapitole „3.2.3. Balíček random_data“. Tato procedura vrací data, která jsou
poté vložena do vytvořené tabulky.
3.2.5.
Pomocné balíčky, funkce a procedury
Dalším balíčkem je log_package, který sice není stěžejní pro samotné generování, ale je
důležitý pro logování vykonaných cyklů. Díky němu je možno odhalit místo vzniku
problému. Procedury tohoto balíčku obsahují autonomní transakce a díky tomu jsou
logovací data zachována, i když dojde během vkládání vygenerovaných dat do nové
tabulky k chybě a následnému roll backu. Můžeme tak zaznamenávat a odhalovat chyby.
Pro proces generování byly použity ještě některé funkce a procedury, které byly
naimplementovány pro tento účel. Tyto metody logicky nesouvisí s žádným z výše
popsaných balíčků a až zde jsou zmíněny pro úplnost. Jedna z těchto funkcí byla popsána
v kapitole „3.1.1. Balíčky, procedury a funkce“. Jednalo se o upravenou funkci pro dělení
dvou čísel.
50
3.3. Export a import velkého množství dat v databázích Oracle
Pro snadný a rychlý přesun velkého množství dat mezi databázemi jsou v technologiích
Oracle navržené datové pumpy. Tyto nástroje slouží k exportu a importu dat na různých
databázích Oraclu. V případě této práce je potřeba přenést vygenerovaná data mezi
testovacím prostředím a produkčním prostředím. Přenesena bude pouze tabulka
vygenerovaných dat. Pro tuto úlohu je potřeba, aby přihlášený uživatel měl dostatečné
oprávnění pracovat s definovaným souborem na databázovém serveru. Nejprve byl
vytvořen ukazatel na existující soubor na databázovém serveru a následně byla uživateli
přidělena práva pracovat s tímto souborem. Potřebné příkazy:
CREATE OR REPLACE DIRECTORY EXP_DIR AS
‘/u01/app/Oracle/oradata’;
GRANT READ, WRITE ON DIRECTORY EXP_DIR TO scott;
Tímto příkazem je uživateli scott uděleno právo pracovat s adresářem exp_dir. Po přidělení
oprávnění lze vygenerovaná data v testovacím prostředí exportovat. Export se spustí tímto
příkazem:
EXPDP scott/tiger tables=GENERATED_TABLE
DIRECTORY=EXP_DIR dumpfile=GENERATED_TABLE.dmp
logfile=expdpGENERATED_TABLE.log
Pomocí následujícího příkazu jsou data importována do produkční databáze.
IMPDP scott/tiger tables=GENERATED_TABLE
DIRECTORY=EXP_DIR dumpfile=GENERATED_TABLE.dmp
logfile=expdpGENERATED_TABLE.log
Je důležité klást důraz na oddělování činností pro testovací a produkční databázi. Je nutné
nezatěžovat produkční databázi činnostmi, které je možné vykonat na testovací databázi.
Toto oddělování činností je důležité i z důvodu bezpečnosti. (16)
51
4.
ZÁVĚR
Cílem mé bakalářské práce bylo vytvořit efektivní nástroj pro generování zátěžových dat a
porozumět principům optimalizace databáze. Této optimalizaci napomáhají i data
vygenerovaná navrženým nástrojem. Při nejobecnějším pohledu není pro zákazníka
důležité, kde se slabé místo informačního systému nachází. Z pohledu uživatele takový
informační systém není prostě optimalizovaný. V tomto případě, kdy problém není přímo
lokalizován, nemusí být chyba v samotné databázi, ale například až u uživatele, který
přistupuje do databáze neefektivně. Proto je velmi důležité porozumět komplexně
procesům databází.
V předchozím odstavci byl zmíněn jeden z důvodů pro testování. Potřeba testování není
důležitá jen při hledání nejslabších míst, ale i při návrhu a zkoušení stability pro budoucí
zátěž systému. Systém nasazovaný na produkční databázi by měl být otestovaný, a pro
takové performance testy je nutné mít potřebná data. Data pro tyto účely se nejlépe
získávají generováním. Jednak můžeme libovolně měnit množství dat, a tím simulovat
různé zátěže, a jednak u tohoto typu testovacích dat nehrozí riziko zneužití citlivých údajů.
Je samozřejmě důležité, aby generovaná data byla správně navržena a odpovídala datům
z reálného provozu databáze. Nejdůležitější vlastností vygenerovaných dat je proto jejich
pravděpodobností rozdělení, které by co nejvíce mělo odpovídat skutečným datům.
Čemu je nutné porozumět před samotným návrhem nástroje pro generování dat a co
všechno je možné v databázi optimalizovat?
Jednak je potřeba nástroj správným způsobem navrhnout, a jednak netestovat pomocí
zátěžových testů něco, co není tímto způsobem testovatelné. Je nutné porozumět principům
běhu databáze. Je potřeba porozumět těmto oblastem:
1. Databázi a způsobu její optimalizace
2. Datovému modelu a business problematice, pro kterou je určen
3. Jak optimalizovat dotazy nad tabulkami
4. Jak efektivně spravovat databázi a datový model
52
Nejdůležitějším z těchto bodů je optimalizace dotazů a optimalizace datového modelu
pomocí indexů. Pokud byly indexy vytvořeny nad správnými sloupci a jsou správně
v dotazech využívány, pak je zvládnuta velká část optimalizace.
Vytipovaná místa databáze dle předešlých bodů by měla být optimalizována a až poté lze
přejít k samotnému testování. Navíc na základě těchto bodů je možné snadněji vyhodnotit
výsledky performance testů.
Samotný nástroj pro generování dat pro zátěžové testy byl navržen tak, aby ke své činnosti
používal indexy tabulek a prostředky PL/SQL pro práci s velkým množstvím dat.
„Nástroj na tvorbu testovacích dat pro zátěžové testování databází“ generuje data, která
odpovídají svým pravděpodobnostním rozdělením statistickým datům o obyvatelích ČR
k 1. 1. 2011.
53
5.
CONCLUSION
The aim of my bachelor thesis was to create an effective tool to generate data for stress
tests and understand the principles of database optimization. The data generated by the
proposed instrument also help to optimize the database. In the most general point of view
is not important for the customer, where the weak point of the information system is
located. From the user´s perspective such information system is not simply optimized. In
this case, when the problem is not directly located, it does not have to be in the database
itself, but the user can access the database inefficiently. Therefore it is very important to
understand the complex processes of databases.
One of the reasons for testing was mentioned in the previous paragraph. The need for
testing is not important only for finding the weakest points, but also in the design and
testing for the future stability of the system load. The system deployed on the production
database should be tested and there is necessary to have data for these performance tests.
The data for these purposes are best obtained by generating. First, we can change the
amount of data, and thus simulate various loads, and also in this type of test data there is no
risk of misuse of sensitive data. Of course it is important that the generated data were
properly designed and reflect the data from the real database. The most important property
of data is the distribution probability, which has to be the same as the probability of the
real data.
What must be understood before design of tool for data generating and what is possible to
be optimized in the database?
Firstly, it is necessary to design the tool by the right way, and secondly it is important that
we do not test the stress tests using something that is not testable in this way. It is
necessary to understand the principles of running the database. You need to understand
these areas:
1. Database and the optimization method
2. Data model and business issue, for which it is intended
3. How to optimize queries for tables
4. How to manage the database and data model effectively
54
The most important of these points is the query optimization and the model optimization
by using indexes. If the indexes were created for the right columns and are properly used in
queries, then a large part of optimization is managed.
The highlighted points of database should be optimized, and then we can go to the actual
testing. Moreover, it is easier to evaluate the results of performance tests on bases of these
points.
The tool for data generating for the stress tests was designed to use for its activity indexes
and sources of PL/SQL. The PL/SQL sources are used to work with large amount of data.
“The tool for creating test data for stress testing DB” generates data, which correspond to
probability distribution of statistical data on the Czech Republic population dated to 1. 1.
2011.
55
6.
ZDROJE
1. Sýkora, Jiří and Sibrt, Tomáš. Analýza pro výkonnostní a zátěžové testy. System
online. [Online] Březen 1, 2009. [Cited: Březen 10, 2012.]
http://www.systemonline.cz/sprava-it/vykonnostni-testy-podnikovych-aplikaci-2-dil.htm.
2. Lacko, L. Správa, programování a použití databázového systému. 2. vydání. Brno :
Computer Press, 2007. p. 576.
3. Using explain plan. Oracle Database Documentation Library 11g Release 2 (11.2).
[Online] Oracle. [Cited: Březen 17, 2012.]
http://docs.oracle.com/cd/E11882_01/server.112/e16638/ex_plan.htm. E16638-06.
4. Indexes and Index-Organized Tables. Oracle Database Documentation Library.
[Online] Oracle. [Cited: Březen 19, 2012.]
http://docs.oracle.com/cd/E14072_01/server.112/e10713/indexiot.htm. E10713-02.
5. Fleming, Matt. How b-tree database indexes work. mattfleming.com. [Online] Únor 22,
2007. [Cited: Březen 29, 2012.] http://mattfleming.com/node/192.
6. BRYLA, Bob and LONEY, Kevin. Mistrovství v Oracle® database 11g. Brno :
Computer Press, a.s., 2009. p. 700. ISBN 978-80-251-2189-4.
7. Solař, Tomáš. Oracle Database 11g: hotová řešení. Brno : Computer Press a.s., 2010.
p. 288. ISBN 978-80-251-2886-2.
8. Oracle Database Performance Tuning Guide, 11g Release 2 (11.2). Oracle
documentation. [Online] [Cited: Březen 15, 2012.]
http://docs.oracle.com/cd/E11882_01/server.112/e16638.pdf. E16638-06.
9. Introduction to the Optimizer. Oracle 9i Database Online Documentation. [Online]
Oracle. [Cited: Březen 18, 2012.]
http://docs.oracle.com/cd/B10501_01/server.920/a96533/optimops.htm#721. A96533-02.
10. Using the Rule-Based Optimizer. Oracle9i Database Online Documentation. [Online]
Oracle. [Cited: Březen 19, 2012.]
http://docs.oracle.com/cd/B10500_01/server.920/a96533/rbo.htm. A96533-02.
11. Managing Optimizer Statistics. Oracle Database Documentation Library. [Online]
Oracle. [Cited: Březen 23, 2012.]
http://docs.oracle.com/cd/E11882_01/server.112/e16638/stats.htm. E16638-06.
12. Oracle Hints. PSOUG.org. [Online] [Cited: Březen 25, 2012.]
56
http://psoug.org/reference/hints.html.
13. Turley, P., Wood, D. Beginning T-SQL with Microsoft SQL Server 2005 and 2008.
Indianapolis : Wrox, 2008. p. 672.
14. PL/SQL. Wikipedie: Otevřená encyklopedie. [Online] Únor 12, 2012. [Cited: Duben 6,
2012.] http://cs.wikipedia.org/wiki/PL/SQL.
15. Feuerstein, S., Pribyl, B. Oracle PL/SQL Programming. 5. vydání. North Sebastopol :
O'Reily Media, 2009. p. 1232.
16. Eckhardt, Erik. Tipy a triky pro Oracle VII. – jak na přenosy velkých dat poprvé.
Databázový svět. [Online] Listopad 21, 2006. [Cited: Duben 5, 2012.]
http://www.dbsvet.cz/view.php?cisloclanku=2006112103.
57
7.
SEZNAM POUŽITÝCH SYMBOLŮ A ZKRATEK
Tabulka 4: Použité symboly a zkratky
Pojem
Popisek
Rowid
Jednoznačná identifikace řádek v tabulce, která umožňuje
nejrychlejší přístup k datům v řádku přímo na místo na
disku.
Funkce/Procedura
Logický celek, který obsahuje jednu funkčnost.
Perzistentní
Ekvivalent je trvalý, většinou se používá ve spojení
s trvalým úložištěm
I/O operace
Operace zápisu a čtení z pevného disku
SLA
Service level agreement je obvykle součástí smlouvy nebo
Technického projektu. Stanovuje parametry výkonu
systému, jeho dostupnosti, rychlosti atd.
OLTP
(Online Transaction Processing) technologie pro ukládání
dat v databázích, která umožňuje snadnou a rychlou
modifikaci dat.
58
8.
SEZNAM OBRÁZKŮ
Obrázek 1: Data masking ..................................................................................................... 16
Obrázek 2: Exekuční plán .................................................................................................... 18
Obrázek 3: B - tree index ..................................................................................................... 23
Obrázek 4: B - strom s nízkou kardinalitou ......................................................................... 24
Obrázek 5: Bitmap index ..................................................................................................... 27
Obrázek 6: Diagram zpracování sql dotazu ......................................................................... 30
Obrázek 7: PL/SQL a SQL engine ...................................................................................... 41
59
9.
SEZNAM TABULEK
Tabulka 1: Popis sloupců exekučního plánu........................................................................ 19
Tabulka 2: Pořadí přístupů, které jsou voleny v RBO ......................................................... 32
Tabulka 3: Internetové stránky, ze kterých byla získána zdrojová data .............................. 43
Tabulka 4: Použité symboly a zkratky ................................................................................. 58
60

Podobné dokumenty

Diplomová práce

Diplomová práce Obr. 59 Char. úhel antény se 4 meandry (w = 16 mm , t = 2.6667 mm).................................. 55 Obr. 60 Proud. rozl. domin. módů, anténa se 4 meandry (w = 16 mm , t = 2.6667 mm)........ 56 ...

Více

Automatic Storage Management (ASM)

Automatic Storage Management (ASM) souborových systémů usnadňuje práci s databází na úrovni dat uložených na disku v Oracle od verze 10g (2003)

Více

Příklad

Příklad hodnot. Mohutnost příkazů je posouzena nesprávně, což může mít vliv na výkon. V určitém okamžiku bude u vyhledávání podle data použit rozsah hodnot indexu, ale u řetězce proběhne úplné prohledávání...

Více

Dizertační práce

Dizertační práce Jak ukazují zkušenosti z nedávných i současných ozbrojených konfliktů, zvyšují se nároky na bojové jednotky a jejich velitele. Rozvoj problematiky počítačové podpory rozhodovacího procesu proto můž...

Více

UNICORN COLLEGE BAKALÁŘSKÁ PRÁCE Efektivní datové

UNICORN COLLEGE BAKALÁŘSKÁ PRÁCE Efektivní datové Systémy pro správu osobních financí mají významnou roli v každodenním osobním životě nespočtu jejich uživatelů. Jejich cílem je pomoci s plánováním a správou osobních financí, poskytnout přehled o ...

Více

Databázové systémy IDS

Databázové systémy IDS síťové a hierarchické) v souvislosti s výrazným růstem požadavků na vývoj datově intenzivních aplikací v 60. letech. Pro tyto systémy bylo typické, že nejprve vznikla nějaká implementace a teprve d...

Více

Kapilární elektoforéza

Kapilární elektoforéza pomocí CE ƒ „Pre-capillary“ provedení : - kapilára je používána pouze pro separaci a detekci

Více

UNICORN COLLEGE BAKALÁŘSKÁ PRÁCE Datové modelování

UNICORN COLLEGE BAKALÁŘSKÁ PRÁCE Datové modelování Prohlašuji, že jsem svou bakalářskou práci na téma datové modelování vypracoval samostatně, pod vedením vedoucího bakalářské práce a s použitím výhradně odborné literatury a dalších informačních zd...

Více