Petra Janc
Priporočila za pisanje povpraševanj SQL
Diplomsko delo
Maribor, avgust 2012
PRIPOROČILA ZA PISANJE POVPRAŠEVANJ
SQL
Diplomsko delo
Študentka: Petra Janc
Študijski program: Visokošolski strokovni, Informatika in tehnologije
komuniciranja
Smer: Tehnologije multimedijskega komuniciranja
Mentorica: red. prof. dr. Tatjana Welzer Družovec, univ. dipl. inž. elektrot.
Somentor: doc. dr. Marko Hölbl, univ. dipl. inž. rač. in inf.
Lektorica: Amadeja Klemenčič, prof. slov.
Maribor, avgust 2012
I
II
ZAHVALA
Zahvaljujem se mentorici red. prof. dr. Tatjani
Welzer Družovec za pomoč in vodenje pri
opravljanju diplomskega dela. Prav tako se
zahvaljujem somentorju doc. dr. Marku Hölblu in
asist. Andreju Sevčnikarju.
Posebna zahvala velja staršem, ki so mi omogočili
študij in me pri tem spodbujali.
III
PRIPOROČILA ZA PISANJE POVPRAŠEVANJ SQL
Ključne besede: SQL povpraševanje, optimizacija SQL povpraševanj, SQL stavki
UDK: 004.65(043.2)
Povzetek:
Diplomsko delo opisuje SQL povpraševanja, oziroma napotke, kako ta povpraševanja
približati optimizaciji. Bralca vodi od začetka pisanja in predstavitve posameznih SQL
stavkov vse do pisanja optimiziranih SQL povpraševanj. Ob tem bralcu predstavi
priporočila in metode za dosego le-teh, poleg tega pa mu predstavi še proces same
optimizacije. Prav tako mu prikaže posamezne korake optimizacije povpraševanj, tako da
jih bralec lahko tudi sam zapiše. Z diplomskim delom želimo ugotoviti, kaj je bistveno pri
pisanju SQL povpraševanj za dosego hitro se izvajajočega povpraševanja, ki porabi čim
manj vira podatkov.
IV
RECOMMENDATIONS FOR WRITING SQL
QUERIES
Key words: SQL Query, SQL Query optimization, SQL clauses
UDK: 004.65(043.2)
Abstract:
This thesis describes SQL Queries and advices how to optimized them. The reader is
guided through from the beginning of writing SQL clauses to writing optimized SQL
queries. By this the reader learn the recommendations and methods to make them
optimized. He is also introduced into the steps of SQL query optimization and he can try
to write them by himself. The objective of this thesis is to learn what is important to make
SQL queries execute faster and use as few data as possible.
V
KAZALO VSEBINE
1 UVOD ...................................................................................................................... 1
2 SQL POVPRAŠEVANJA ....................................................................................... 3
2.1 OBLIKOVANJE PODATKOVNEGA MODELA ......................................................... 3
2.2 PRIPOROČILA ZA PISANJE POVPRAŠEVANJ SQL ................................................ 4
2.3 OPIS SQL POVPRAŠEVANJ IN STAVKOV ............................................................ 4
2.4 SELECT STAVEK ............................................................................................. 5
2.5 LOGIČNI OPERATORJI ....................................................................................... 6
2.6 OPERACIJE ........................................................................................................ 8
2.7 STAVKI ZA UPRAVLJANJE Z PODATKOVNO BAZO ..............................................11
2.8 OSTALI STAVKI ................................................................................................14
2.9 PRIMERJALNI OPERATORJI ..............................................................................18
2.10 SQL VGNEZDENO POVPRAŠEVANJE..................................................................20
2.11 VARNOST PODATKOV V PODATKOVNI BAZI ......................................................21
2.12 POGLEDI (ANGL. VIEW) ...................................................................................23
3 PRIPOROČILA ZA PISANJE POVPRAŠEVANJ SQL .....................................25
3.1 PROCESIRANJE SQL STAVKOV ........................................................................25
3.2 OPTIMIZACIJA CELOTNEGA POSTOPKA SQL-A ................................................30
3.3 OPTIMIZACIJA SQL POVPRAŠEVANJ ................................................................31
3.4 METODE IN TEHNIKE PISANJA OPTIMIZIRANIH SQL POVPRAŠEVANJ...............33
3.5 KORAKI OPTIMIZIRANJA .................................................................................42
3.6 PRIPOMOČKI ZA OPTIMIZIRANJE SQL POVPRAŠEVANJ....................................44
4 SKLEP ....................................................................................................................50
5 VIRI ........................................................................................................................51
VI
KAZALO SLIK
Slika 2.1 ER-model ........................................................................................................... 3
Slika 2.2 Rezultat povpraševanja SELECT ........................................................................ 6
Slika 2.3 Rezultati povpraševanja AND ............................................................................ 6
Slika 2.4 Rezultat povpraševanja OR ................................................................................ 7
Slika 2.5 Rezultat povpraševanja NOT .............................................................................. 7
Slika 2.6 Rezultat povpraševanja EXISTS ......................................................................... 8
Slika 2.7 Rezultat povpraševanja UNION ......................................................................... 9
Slika 2.8 Rezultat povpraševanja MINUS ........................................................................10
Slika 2.9 Rezultati povpraševanja INTERSECT ...............................................................11
Slika 2.10 Rezultati INSERT ukaza..................................................................................12
Slika 2.11 Rezultati UPDATE ukaza ................................................................................13
Slika 2.12 Rezultati DELETE ukaza ................................................................................14
Slika 2.13 Rezultati povpraševanja HAVING...................................................................15
Slika 2.14 Rezultati povpraševanja GROUP BY ..............................................................16
Slika 2.15 Rezultati povpraševanja ORDER BY ..............................................................17
Slika 2.16 Rezultati povpraševanja DECODE ..................................................................18
Slika 2.17 Rezultati povpraševanja IN ..............................................................................19
Slika 2.18 Rezultati povpraševanja LIKE .........................................................................19
Slika 2.19 Rezultati povpraševanja BETWEEN ...............................................................20
Slika 2.20 Rezultat vgnezdenega povpraševanja ...............................................................21
Slika 3.1 Proces SQL-a [14] .............................................................................................26
Slika 3.2 CBO arhitektura [14] .........................................................................................27
VII
Slika 3.3 Faze procesiranja SQL stavkov [16] ..................................................................29
Slika 3.4 Celotna optimizacija [23] ..................................................................................30
Slika 3.5 Rezultat povpraševanja za hitrejše izvajanje ......................................................34
Slika 3.6 Rezultat HAVING povpraševanja......................................................................35
Slika 3.7 Rezultat HAVING povpraševanja......................................................................35
Slika 3.8 Rezultati vgnezdenega povpraševanja ................................................................36
Slika 3.9 Rezultati EXSIST povpraševanja .......................................................................36
Slika 3.10 Rezultati DISTINCT ukaza .............................................................................37
Slika 3.11 Rezultati EXISTS ukaza ..................................................................................37
Slika 3.12 Rezultati UNION povpraševanja .....................................................................38
Slika 3.13 Rezultati DECODE ukaza ...............................................................................39
Slika 3.14 Rezultati povpraševanja ...................................................................................39
Slika 3.15 Rezultati vzdevkov tabel..................................................................................40
Slika 3.16 Rezultati WHERE povpraševanja ....................................................................40
Slika 3.17 SQL Query Analyzer .......................................................................................44
Slika 3.18 Navigacijska plošča .........................................................................................45
Slika 3.19 Podokno za SQL tekst .....................................................................................45
Slika 3.20 Podokno za SQL tekst z uporabo TopSQL in SQL History ..............................45
Slika 3.21 Podokno podrobnosti .......................................................................................46
VIII
UPORABLJENE KRATICE
SQL Structured Query Language
SUPB Sistem za upravljanje s podatkovno bazo
RBO Rule-based optimizer
CBO Cost-based optimizer
I/O Input/Output
CPU Central Processor Unit
SP Stored Procedure
DML Data Manipulation Language
DBA Data Base Administrator
Priporočila za pisanje SQL stavkov Stran 1
1 UVOD
Končni uporabniki aplikacij oziroma programov pričakujejo od njih, da so le ti preprosti za
uporabo in se hitro odzivajo na njihove ukaze, za kar morajo poskrbeti razvijalci aplikacij.
Ko pa imamo končno aplikacijo že na trgu, je vzdrževalec oziroma skrbnik odgovoren za
vzdrževanje aplikacije, da se le ta ne upočasni, poslabša ali celo preneha delovati. Na to pa
imajo zelo velik vpliv SQL povpraševanja, s katerimi je narejena aplikacija in preko
katerih ta dostopa do želenih informacij iz podatkovne baze. Pri tem je pomembno okolje
SQL povpraševanja, katero moramo ves čas spremljati ali se ta spreminja in kako se na to
spremembo odzove aplikacija ter znotraj te tudi povpraševanje.
Veliko posameznikov se ukvarja s pisanjem tako imenovanih amaterskih SQL
povpraševanj, vendar se ta po navadi ne odzivajo tako hitro, kot bi si želeli. Da pa bi
dosegli prav to moramo povpraševanja čim bolj optimizirati. Torej uporabimo tako
imenovano optimizacijo SQL povpraševanj.
Prav to je namen diplomskega dela: predstavitev priporočil, metod in načinov pisanja SQL
povpraševanj ter pripomočkov, ki nam to delo olajšajo, tako posameznikom kot podjetjem.
Najbolj pomembno je, da se povpraševanja izvajajo hitro, so enostavna in porabijo čim
manj virov podatkov. Primeri v diplomskemu delu so narejeni samo kot primeri in se ne
uporabljajo v obstoječih aplikacijah. Pri načinu optimizacije in njene uporabe pa se
nanašajo pretežno na orodje Oracle in njegove pripomočke za delo z SQL povpraševanji in
podatkovno bazo.
Prvo poglavje nam predstavi, kako začeti optimizacijo že pri oblikovanju podatkovnega
modela, razloži nam postopek od oblikovanja entitetno-relacijskega podatkovnega modela
pa vse do SQL povpraševanj. Iz tega poglavja lahko izvemo, kako je sestavljeno
povpraševanje in katere vrste stavkov poznamo ter kako jih uporabimo v praksi. Kar pa je
razloženo na enostavnih primerih. Nekateri od stavkov so podrobneje razloženi. Na kratko
se dotaknemo tudi varnosti in upravljanja dostopa do podatkovne baze ter prednosti in
slabosti uporabe pogledov (angl. view). Temu sledi drugo poglavje, v katerem predstavimo
kako uporabiti metode in napotke oziroma priporočila, da se lahko približamo
optimiziranemu SQL povpraševanju, kar pa je tudi glavna tema diplomskega dela.
Začnemo že pri samemu procesiranju SQL stavkov in nadaljujemo z optimizacijo
celotnega postopka SQL-a ter opisa poteka optimizacije SQL povpraševanj. Pri tem
Priporočila za pisanje SQL stavkov Stran 2
spoznamo tehnike za pisanje optimiziranih povpraševanj in kako jih pravilno uporabiti, kar
pa je prikazano z enostavnimi primeri. Prav tako se na kratko seznanimo s koraki
optimizacije, to je kako optimizirati povpraševanje že od samega začetka. Na koncu
izvemo katero Oraclovo orodje nam lahko pri optimizaciji olajša delo in kako upravljati z
njim. V zaključku pa so podane ugotovitve in spoznanja.
Priporočila za pisanje SQL stavkov Stran 3
2 SQL POVPRAŠEVANJA
2.1 Oblikovanje podatkovnega modela
Preden začnemo s pisanjem SQL povpraševanj, moramo najprej izoblikovati podatkovno
bazo. To storimo tako, da najprej izdelamo entitetno-relacijski podatkovni model (
Slika 2.1). V našem primeru smo to izvedli z Oraclovim orodjem SQL DataModeler. Sprva
moramo zapisati entitete oziroma imena tabel, katere praviloma zapišemo v množinski
obliki in v samostalniku, vendar obstajajo tudi orodja, ki tega ne podpirajo. Nato te entitete
logično povežemo med seboj z relacijami. To običajno zapišemo v obliki stavka, ki ga
sestavlja osebek, povedek in predmet. Osebek in predmet sta pri tem entiteti, povedek pa je
relacija. Nato te entitete napolnimo z atributi. Vsakemu atributu moramo določiti tip, ta je
največkrat integer, varchar ali double. Vendar obstaja še veliko število drugih tipov.
Določimo tudi kateri od atributov je primarni ključ in kateri so sekundarni ključi.
Sekundarnih ključev za razliko od primarnih ni v vsaki entiteti. Na koncu določimo še ali
je atribut lahko NULL oziroma brez vrednosti. Ko smo vse to že storili, še relacijam
določimo kardinalnosti, te pa so lahko 1:M (ena:mnogo), 1:1 (ena:ena) in M:N
(mnogo:mnogo). Pri tem kardinalnost M:N ni zaželena, zato jo nadomestimo z dvema
novima relacijama, in sicer s kardinalnostmi 1:M in M:1 ter novo entiteto. Da je naša baza
uporabna, jo moramo napolniti še s podatki, s katerimi bomo kasneje upravljali.
Slika 2.1 ER-model
Priporočila za pisanje SQL stavkov Stran 4
2.2 Priporočila za pisanje povpraševanj SQL
Ko začnemo s sestavljanjem SQL povpraševanj, moramo vedeti, kaj pričakujemo kot
rezultat. Zamisliti si moramo, katere atribute in funkcije je potrebno izluščiti, da jih bomo
uporabili v stavku SELECT. Tako bomo lažje ugotovili, katere stavke bomo uporabili in
ali bomo uporabili vgnezdena povpraševanja. Nato izberemo tabele iz podatkovne baze, ki
jih bomo potrebovali in jih zapišemo v FROM stavek. Pri tem moramo natančno razmisliti,
katere od teh tabele bomo resnično potrebovali, da ne bi prišlo do nepotrebnega
podaljševanja izvajalnega časa povpraševanja. Če naše povpraševanje vključuje več tabel,
moramo te med seboj tudi povezati. To storimo v stavku WHERE z enačenjem ustreznih
atributov. Nadalje lahko v tem stavku zapisujemo pogoje, ki morajo biti izpolnjeni v
povpraševanju. Šele ko smo napisali vse te stavke, je naše povpraševanje pripravljeno za
izvajanje. [1]
2.3 Opis SQL povpraševanj in stavkov
SQL je strukturiran povpraševalni jezik za organiziranje, vodenje, reševanje in dostop do
podatkov shranjenih v podatkovni bazi. Če želimo pridobiti določene podatke iz
podatkovne baze, moramo napisati SQL zahtevo. Nato nam sistem za upravljanje s
podatkovno bazo ali SUPB proces poišče zahtevane podatke v podatkovni bazi ter nam
vrne rezultat. Takšen proces imenujemo SQL povpraševanje. [2] Ta povpraševanja so
sestavljena iz tako imenovanih SQL stavkov.
Poznamo več vrst stavkov, SELECT stavek in pogojne stavke, kot so AND, OR, NOT in
EXISTS … operacije UNION, MINUS, INTERSECT … stavke za upravljanje z bazo
INSERT, UPDATE, DELETE … primerjalne operatorje IN, LIKE, BETWEEN … in še
nekaj pomembnejših stavkov kot so IN, LIKE, BETWEEN … Razen naštetih obstaja še
mnogo stavkov in ukazov, ki jih bomo delno spoznali v nadaljevanju diplomskega dela.
Priporočila za pisanje SQL stavkov Stran 5
SQL ni občutljiv na velike črke, tako se npr. SELECT obravnava enako kot, če bi napisali
select. Vendar pa zaradi boljše preglednosti ukaze pišemo z velikimi tiskanimi črkami,
imena stolpcev, tabel in pogoje pa z malimi tiskanimi črkami. Prav tako znakovni in
časovni predikat zapišemo med enojnimi narekovaji ( ' ). Vrednost, ki jo v stavku WHERE
primerjamo s poljem iz tabele, mora biti enakega tipa kot podatkovni tip polja.
SQL povpraševanje (Primer 2.1) mora vsebovati SELECT in FROM stavek, vsi nadaljnji
pa so poljubni.
SELECT A1, A2, …, An ali SELECT *
FROM R1, R2, … Rm
(WHERE »Pogoj«);
Primer 2.1 Struktura SQL povpraševanja
Kot razlago zgornjega primera lahko podamo, da SELECT omogoča oblikovanje seznama
podatkov, katere bi radi dobili za rezultat, FROM pa omogoča oblikovanje seznama relacij.
WHERE omogoča vstavljanje pogojev. * pomeni, da želimo izbrati vse stolpce v tabeli. [1]
Na koncu vsakega povpraševanja moramo dodati podpičje ( ; ), kar nakazuje, da je naše
povpraševanje dokončano in je pripravljeno za izvedbo.
2.4 SELECT stavek
Ta nam omogoča oblikovanje seznama podatkov, katerega dobimo kot rezultat iz
podatkovne baze. Ima več neobveznih stavkov, od tega sta samo SELECT in FROM tista,
ki sta obvezna (Primer 2.2). [3]
SELECT [ ALL | DISTINCT ] imena stolpcev
FROM imena tabel
[ WHERE » pogoji « ]
[ GROUP BY » seznam vrstic « ]
[ HAVING » pogoji « ]
[ ORDER BY » seznam vrstic « [ ASC | DESC] ]
Primer 2.2 Sintaksa SELECT stavka
Priporočila za pisanje SQL stavkov Stran 6
Povpraševanje (Primer 2.3) nam kot rezultat vrne imena in priimke ter vpisne številke
študentov, ki študirajo na smeri ITK (Slika 2.2).
SELECT s.ime_in_priimek, s.vpisna_stevilka
FROM studentje s, smeri r
WHERE r.id_smeri = s.id_smeri
AND r.naziv_smeri = 'ITK';
Primer 2.3 Sintaksa uporabe SELECT stavka
Slika 2.2 Rezultat povpraševanja SELECT
2.5 Logični operatorji
Poznamo več vrst logičnih operatorjev AND, OR, NOT in EXISTS. Vsi ti operatorji
zavzamejo vrednosti resnično (angl. true), neresnično (angl. false) ali neznano (angl.
unknown). [4]
Operator AND vsebuje dva operanda, ki sta lahko primerjava ali logična izraza. Vrne nam
rezultat true, če sta oba operanda true in rezultat false, če je vsaj en od operandov false.
V vseh ostalih primerih, ki niso omenjeni zgoraj, vrne rezultat unknown. [5]
Povpraševanje (Primer 2.4) nam kot rezultat vrne vse podatke o študentih, ki so v 2. letniku
in so starejši od 20 let (Slika 2.3).
SELECT *
FROM studentje
WHERE letnik= 2 AND starost > 20;
Primer 2.4 Sintaksa uporabe pogojev AND
Slika 2.3 Rezultati povpraševanja AND
Priporočila za pisanje SQL stavkov Stran 7
Operator OR vsebuje dva operanda, ki sta lahko primerjava ali logična izraza.
Vrne rezultat true, če je vsaj en od operandov true in rezultat false, če sta oba operanda
false. V vseh ostalih primerih, ki niso omenjeni zgoraj pa vrne rezultat unknown. [5]
Povpraševanje (Primer 2.5) nam kot rezultat vrne vse podatke o študentih, ki imajo
povprečno oceno 8.6 ali 7 (Slika 2.4).
SELECT *
FROM studentje
WHERE povprecna_ocena = 8.6 OR povprecna_ocena = 7;
Primer 2.5 Sintaksa uporabe pogojev OR
Slika 2.4 Rezultat povpraševanja OR
Operator NOT rezultatu primerjave ali rezultatu logičnega izraza zamenja vrednost.
Vrne rezultat true, če je dejanski rezultat false in rezultat false, če je dejanski rezultat true.
V vseh ostalih primerih pa vrne rezultat unknown. [5]
Povpraševanje (Primer 2.6) nam kot rezultat vrne vse podatke o študentih, ki nimajo
statusa (Slika 2.5).
SELECT *
FROM studentje
WHERE NOT status='DA';
Primer 2.6 Sintaksa uporabe pogojev NOT
Slika 2.5 Rezultat povpraševanja NOT
Priporočila za pisanje SQL stavkov Stran 8
Operator EXISTS se uporablja za iskanje prisotnosti vrstic v določeni tabeli, ki je v stiku z
zanesljivim kriterijem. Vrne nam vrednost true, če vgnezdeno povpraševanje vrne vsaj eno
vrstico. V ostalih primerih pa se povpraševanje ne izvede in prav tako ne vrne rezultata. [8]
Povpraševanje (Primer 2.7) nam kot rezultat vrne id_fakultete in naziv fakultete, ki ima
smer ITK (Slika 2.6).
SELECT id_fakultete, naziv
FROM fakultete f
WHERE EXISTS ( SELECT *
FROM smeri s
WHERE s.id_fakultete=f.id_fakultete
AND naziv_smeri='ITK' );
Primer 2.7 Sintaksa uporabe pogojev EXISTS
Slika 2.6 Rezultat povpraševanja EXISTS
2.6 Operacije
Poznamo več vrst operacij, ene izmed najpomembnejših so UNION, MINUS,
INTERSECT …
Operacija UNION (Primer 2.8) združi rezultate dveh ali več povpraševanj v enojni rezultat.
Glavni pravili za združevanje rezultatov več povpraševanj sta, da mora biti število in vrstni
red stolpcev v vseh povpraševanjih enako in oblika datuma združljiva. Privzeto nam
UNION pobriše podvojene rezultate, če pa tega ne želimo uporabimo UNION ALL. [6]
SELECT ime_stolpca1, ime_stolpca2, … ime_stolpca_n
FROM ime_tabele
UNION / UNION ALL
SELECT ime_stolpca1, ime_stolpca2, ... ime_stolpca_n
FROM ime_tabele;
Primer 2.8 Sintaksa operacije UNION
Priporočila za pisanje SQL stavkov Stran 9
Povpraševanje (Primer 2.9), pri katerem uporabimo UNION ALL, nam kot rezultat vrne,
imena in priimke študentov, ki študirajo na smeri RIT in imena in priimke študentov, ki
študirajo na smeri ITK, prav tako izpiše študenta, ki študira na smeri ITK kot tudi na smeri
RIT (Slika 2.7). Če pa bi uporabili samo UNION, bi tega študenta izpisalo samo enkrat.
SELECT s.ime_in_priimek
FROM studentje s, smeri r
WHERE (r.id_smeri = s.id_smeri
AND r.naziv_smeri='RIT')
UNION ALL
SELECT s.ime_in_priimek
FROM studentje s, smeri r
WHERE (r.id_smeri = s.id_smeri
AND r.naziv_smeri='ITK');
Primer 2.9 Sintaksa uporabe operacije UNION
Slika 2.7 Rezultat povpraševanja UNION
Operacija MINUS (Primer 2.10) se uporablja, da lahko izločimo rezultat drugega
povpraševanja iz rezultatov prvega povpraševanja. Vzame rezultate prvega povpraševanja
in nato iz tega izloči rezultat drugega povpraševanja. Če drugo povpraševanje vsebuje
rezultat, ki ni v prvem povpraševanju, ga zanemari. Oba povpraševanja morata imeti enako
strukturo in število, vrstni red stolpcev in združljivo obliko datuma.
Poleg tega MINUS izloči vse podvojene vrstice. [7]
SELECT ime_stolpca1, ime_stolpca2, … ime_stolpca_n
FROM ime_tabele
[ WHERE » pogoji « ]
MINUS
SELECT ime_stolpca1, ime_stolpca2, … ime_stolpca_n
FROM ime_tabele
[ WHERE » pogoji « ];
Primer 2.10 Sintaksa operacije MINUS
Priporočila za pisanje SQL stavkov Stran 10
Povpraševanje (Primer 2.11) nam kot rezultat vrne vse podatke o študentih, ki so stari od
18 do 27, razen tistih, ki imajo starost med 21 in 23 (Slika 2.8).
SELECT *
FROM studentje
WHERE starost BETWEEN 18 AND 27
MINUS
SELECT *
FROM studentje
WHERE starost BETWEEN 21 AND 23;
Primer 2.11 Sintaksa uporabe operacije MINUS
Slika 2.8 Rezultat povpraševanja MINUS
Operacija INTERSECT (Primer 2.12) se obnaša kot operator AND. Vrne nam rezultat
samo tistih podatkov, ki so enaki tako v prvemu povpraševanju kot v drugemu
povpraševanju. Oba pa morata imeti isto število in vrstni red stolpcev ter združljivo obliko
datumov. INTERSECT izloči ponavljajoče se rezultate, obraten učinek pa dobimo, če
uporabimo INTERSECT ALL. [7]
SELECT ime_stolpca1, ime_stolpca2, … ime_stolpca_n
FROM ime_tabele
INTERSECT/INTERSECT ALL
SELECT ime_stolpca1, ime_stolpca2, … ime_stolpca_n
FROM ime_tabele;
Primer 2.12 Sintaksa operacije INTERSECT
Priporočila za pisanje SQL stavkov Stran 11
Povpraševanje (Primer 2.13) nam kot rezultat vrne ime in priimek študenta, ki študira tako
na smeri ITK kot na smeri RIT (Slika 2.9).
SELECT s.ime_in_priimek
FROM studentje s, smeri r
WHERE (r.id_smeri = s.id_smeri
AND r.naziv_smeri='RIT')
INTERSECT
SELECT s.ime_in_priimek
FROM studentje s, smeri r
WHERE (r.id_smeri = s.id_smeri
AND r.naziv_smeri='ITK');
Primer 2.13 Sintaksa uporabe operacije INTERSECT
Slika 2.9 Rezultati povpraševanja INTERSECT
2.7 Stavki za upravljanje z podatkovno bazo
Poznamo ukaze kot so INSERT, UPDATE in DELETE, ki jih uporabljamo za delo z
podatkovno bazo.
Ukaz INSERT (Primer 2.14) nam omogoča vstavljanje posameznih podatkov v tabelo.
Vrstni red vrednosti, ki jih vstavimo, mora biti v enakem vrstnem redu kot so stolpci v
tabeli. Največkrat ga uporabimo v kombinaciji z INTO. [6]
INSERT INTO ime_tabele (ime_stolpca1, ime_stolpca2, … ime_stolpca_n)
VALUES (vrednost1, vrednost2, ... vrednost_n);
Primer 2.14 Sintaksa ukaza INSERT
Priporočila za pisanje SQL stavkov Stran 12
V tabelo NASLOVI vstavimo id naslova, stalni naslov, hišno številko in id pošte (Primer
2.15, Slika 2.10).
INSERT INTO naslovi (id_naslova, stalni_naslov, hisna_stevilka, id_poste)
VALUES (1, 'Smetanova ulica', 17, 2 );
Primer 2.15 Sintaksa uporabe ukaza INSERT
Slika 2.10 Rezultati INSERT ukaza
Ukaz UPDATE (Primer 2.16) nam omogoča posodobitev že obstoječih vrednosti v tabelah.
[6]
UPDATE ime_tabele
INSERT ime_stolpca1=vrednost1, ime_stolpca2=vrednost2, ...
ime_stolpca_n=vrednost_n
WHERE neko_ime_stolpca=neka_vrednost;
Primer 2.16 Sintaksa ukaza UPDATE
Priporočila za pisanje SQL stavkov Stran 13
Vsem študentom v tabeli spremenimo starost z 21 let na 22 let (Primer 2.17, Slika 2.11).
UPDATE studentje
SET starost=22
WHERE starost=21;
Primer 2.17 Sintaksa uporabe ukaza UPDATE
Slika 2.11 Rezultati UPDATE ukaza
Ukaz DELETE (Primer 2.18) nam omogoča, da lahko izbrišemo že obstoječe vrednosti iz
tabele. [6]
DELETE FROM ime_tabele
WHERE ime_stolpca= vrednost;
Primer 2.18 Sintaksa ukaza DELETE
Priporočila za pisanje SQL stavkov Stran 14
Izbrišemo naziv smeri mehatronika iz tabele smeri (Primer 2.19) (Slika 2.12).
DELETE FROM smeri
WHERE naziv_smeri='Mehatronika';
Primer 2.19 Sintaksa uporabe ukaza DELETE
Slika 2.12 Rezultati DELETE ukaza
2.8 Ostali stavki
Poznamo veliko število stavkov, toda največkrat uporabljeni, poleg že zgoraj naštetih, so
HAVING, GROUP BY, ORDER BY, DECODE …
HAVING (Primer 2.20) se uporablja v SELECT stavku največkrat v kombinaciji z
GROUP BY ukazom. V primeru, ko tega v stavku nimamo, se HAVING obnaša kot
Priporočila za pisanje SQL stavkov Stran 15
WHERE ukaz. Njegovi argumenti morajo imeti le eno vrednost za eno skupino zapisov.
[6]
SELECT ime_stolpca1, ime_stolpca2, ... ime_stolpca_n, matematična_formula
FROM ime_tabele
GROUP BY ime_stolpca1, ime_stolpca2, ... ime_stolpca_n
HAVING pogoj1 ... pogoj_n;
Primer 2.20 Sintaksa ukaza HAVING
Povpraševanje (Primer 2.21) nam kot rezultat vrne združene podatke imen in priimkov
študentov, ki imajo minimalno povprečno oceno nižjo od 7 (Slika 2.13).
SELECT ime_in_priimek, MIN (povprecna_ocena)
FROM studentje
GROUP BY ime_in_priimek
HAVING MIN (povprecna_ocena) < 7 ;
Primer 2.21 Sintaksa uporabe ukaza HAVING
Slika 2.13 Rezultati povpraševanja HAVING
GROUP BY (Primer 2.22) se uporablja v zvezi z združevalnimi funkcijami za grupiranje
rezultatov enega ali več stolpcev. Priredi vrednost skupinske funkcije vsaki skupini
posebej. Če za argument uporabimo primarni ključ, nam more ta vrniti toliko zapisov kot
jih je v tabeli. [6]
SELECT ime_stolpca1, ime_stolpca2, ... ime_stolpca_n, matematična_formula
FROM ime_tabele
WHERE ime_stolpca vrednost operatorja
GROUP BY ime_stolpca;
Primer 2.22 Sintaksa ukaza GROUP BY
Priporočila za pisanje SQL stavkov Stran 16
Povpraševanje (Primer 2.23) nam kot rezultat vrne imena in priimke študentov in njihovo
največjo povprečno oceno. V primeru da je študent vpisan na dve smeri, kot rezultat
dobimo njegovo večjo povprečno oceno. Če bi spustili stavek GROUP BY, bi kot rezultat
dobili podvojena imena in priimke študentov (Slika 2.14).
SELECT ime_in_priimek, MAX (povprecna_ocena)
FROM studentje
GROUP BY ime_in_priimek;
Primer 2.23 Sintaksa uporabe ukaza GROUP BY stavek
Slika 2.14 Rezultati povpraševanja GROUP BY
ORDER BY (Primer 2.24) se uporablja za razvrščanje dobljenih rezultatov glede na en
stolpec. Privzeto se razvršča podatke naraščajoče ASC. Poznamo pa tudi padajoče
razvrščanje DESC. [6]
SELECT ime_stolpca1, ime_stolpca2, ... ime_stolpca_n
FROM ime_tabele
ORDER BY ime_stolpca ASC|DESC;
Primer 2.24 Sintaksa ukaza ORDER BY
Priporočila za pisanje SQL stavkov Stran 17
Povpraševanje (Primer 2.25) nam kot rezultat vrne vse podatke o študentih razvrščenih
naraščajoče po imenih in priimkih študentov (Slika 2.15).
SELECT *
FROM studentje
ORDER BY ime_in_priimek;
Primer 2.25 Sintaksa uporabe ukaza ORDER BY
Slika 2.15 Rezultati povpraševanja ORDER BY
DECODE (Primer 2.26) ima funkcionalnost, kot če bi uporabili IF-THEN-ELSE stavek.
[10]
SELECT ime_stolpca, decode (izraz, iskanje, rezultat [, iskanje,
rezultat]… [, privzeto])
FROM ime_tabele;
Pri tem pomeni:
Izraz: je vrednost, ki jo primerjamo.
Iskanje: je vrednost, ki jo primerjamo z izrazom.
Rezultat: je vrednost, ki jo dobimo, je če izraz enak iskanju.
Privzeto: je opcijsko. Če se ne ujema, se vrne privzeti rezultat. Če
privzetega rezultata ne podamo, se vrne NULL.
Primer 2.26 Sintaksa ukaza DECODE
Priporočila za pisanje SQL stavkov Stran 18
Povpraševanje (Primer 2.27) nam kot rezultat vrne ime in priimek študenta, katerega id je
69, kar pomeni, da je študent na univerzi Ljubljana, drugače pa je na univerzi Maribor
(Slika 2.16).
SELECT ime_in_priimek, decode (id_studenta, 69, 'Ljubljana', 'Maribor'
)
FROM studentje;
Primer 2.27 Sintaksa uporabe ukaza DECODE
Slika 2.16 Rezultati povpraševanja DECODE
2.9 Primerjalni operatorji
Uporabljamo jih za izboljšanje zmožnosti iskanja SQL povpraševanja. Poznamo
operatorje, kot so IN, LIKE, BETWEEN … Z vsemi operatorji lahko uporabimo ukaz
NOT.
IN operator (Primer 2.28) uporabimo takrat, kadar želimo primerjati stolpec z več
vrednosti. Obnaša se podobno kot operator OR. [4] [9]
SELECT ime_stolpca1, ime_stolpca2, ... ime_stolpca_n
FROM ime_tabele
WHERE ime_stolpca IN vrednost;
Primer 2.28 Sintaksa operatorja IN
Priporočila za pisanje SQL stavkov Stran 19
Povpraševanje (Primer 2.29) nam kot rezultat vrne ime in priimek ter letnik študenta, ki je
vpisan v absolventski staž ali tretji letnik (Slika 2.17).
SELECT ime_in_priimek, letnik
FROM studentje
WHERE letnik IN ('ABS', '3');
Primer 2.29 Sintaksa uporabe operatorja IN
Slika 2.17 Rezultati povpraševanja IN
LIKE operator (Primer 2.30) uporabimo, da naredimo seznam vseh vrstic v tabeli, kjer se
vrednosti stolpcev ujemajo z določenim vzorcem. Največkrat ga uporabimo, kadar želimo
pregledati vrednost vrstice, da jih primerjamo z določeno vrednostjo, ali takrat ko ne vemo
točne vrednosti. Za to po navadi napišemo zraven znak %, kar pomeni, da iščemo po
začetnih vrednostih. Prav tako lahko uporabimo znak _, kar predstavlja enojni znak.
Uporabljamo ga le s polji, ki so tipa char ali varchar. [4] [9]
SELECT ime_stolpca1, ime_stolpca2, ... ime_stolpca_n
FROM ime_tabele
WHERE ime_stolpca LIKE like_pogoj;
Primer 2.30 Sintaksa LIKE operatorja
Povpraševanje (Primer 2.31) nam kot rezultat vrne ime in priimek študenta, katerega ime
se začne na črko A (Slika 2.18).
SELECT ime_in_priimek
FROM studentje
WHERE ime_in_priimek LIKE 'A%';
Primer 2.31 Sintaksa uporabe operatorja LIKE
Slika 2.18 Rezultati povpraševanja LIKE
Priporočila za pisanje SQL stavkov Stran 20
BETWEEN operator (Primer 2.32) uporabimo za primerjanje podatkov v nekem območju
vrednosti. Je občutljiv na vrstni red, zato moramo zapisati vrednost1 <= vrednost2. [4] [9]
SELECT ime_stolpca1, ime_stolpca2, ... ime_stolpca_n
FROM ime_tabele
WHERE ime_stolpca BETWEEN nizja_vrednost AND visja_vrednost;
Primer 2.32 Sintaksa operatorja BETWEEN
Povpraševanje (Primer 2.33) nam kot rezultat vrne ime, priimek in starost študenta, ki je
star med 20 in 22 let (Slika 2.19).
SELECT ime_in_priimek, starost
FROM studentje
WHERE starost BETWEEN 20 AND 22;
Primer 2.33 Sintaksa uporabe operatorja BETWEEN
Slika 2.19 Rezultati povpraševanja BETWEEN
2.10 SQL vgnezdeno povpraševanje
Je tako rekoč samo povpraševanje v povpraševanju. Vključimo ga v WHERE ali
HAVING stavek osnovnega povpraševanja. Na tak način lažje pridobimo podatke iz več
tabel (Primer 2.34). [4]
SELECT ime_stolpca1, ime_stolpca2, ... ime_stolpca_n
FROM ime_tabele
WHERE ime_stolpca [Primerjalni operator]
(SELECT ime_stolpca
FROM ime_tabele
WHERE [Pogoj])
Primer 2.34 Sintaksa vgnezdenega povpraševanja
Priporočila za pisanje SQL stavkov Stran 21
Povpraševanje (Primer 2.35) nam kot rezultat vrne vse podatke o študentu, ki ima najvišjo
povprečno oceno (Slika 2.20).
SELECT *
FROM studentje
WHERE povprecna_ocena = (SELECT MAX (povprecna_ocena)
FROM studentje);
Primer 2.35 Sintaksa uporabe vgnezdenega povpraševanja
Slika 2.20 Rezultat vgnezdenega povpraševanja
2.11 Varnost podatkov v podatkovni bazi
Zelo pomembno je, kako dostopamo do podatkovne baze. Kajti podatki v podatkovni bazi
so lahko ogroženi, če ima dostop oseba, ki bi jih lahko na kakršen koli način poškodovala
ali uničila. Zaradi tega lahko posameznim osebam ali skupini oseb dodelimo določene
pravice za delo s podatki v podatkovni bazi.
Varnost teh podatkov temelji na treh glavnih konceptih. In sicer uporabnikih, to so
ustvarjalci podatkovne baze. Objektih podatkovne baze, za katere lahko uporabimo tako
rekoč zavarovanje, kot so tabele, pogledi, forme itd. In na pravicah, to pomeni, da ima
lahko vsak uporabnik določene različne pravice npr. nekateri uporabniki lahko dodajajo
tabele, stolpce, ne morejo pa jih brisati itd. [2]
Pravice za dostop do podatkov v tabelah za posamezne uporabnike lahko določimo z
GRANT ali z REVOKE ukazom, te največkrat določi kar lastnik tabele ali administrator
podatkovne baze. [2]
Z GRANT (Primer 2.36) določimo, kateri uporabniki imajo pravico dostopati oziroma
upravljati s podatkovnimi objekti. Ti morajo pred tem že imeti veljaven uporabniški račun.
[2] [4]
GRANT pravice
ON ime_objekta
TO {ime_uporabnika |PUBLIC |ime_skupine}
[WITH GRANT OPTION];
Primer 2.36 Sintaksa GRANT ukaza
Priporočila za pisanje SQL stavkov Stran 22
S pravicami določimo uporabniku na kakšen način lahko uporablja podatkovne objekte, ti
ukazi so ALL, EXECUTE, SELECT, INSERT, UPDATE, DELETE, REFERENCES,
ALERT in INDEX.
Ime_objekta je objekt podatkovne baze in je lahko TABLE, VIEW, STORED PROC ali
SEQUENCE.
Ime_uporabnika je uporabnik, kateremu so namenjene te pravice.
PUBLIC pomeni, da so te pravice določene za vse uporabnike.
Ime_skupine pomeni, da te pravice določimo neki skupini uporabnikov.
Z WITH GRANT OPTION določimo, da lahko uporabnik upravlja s pravicami drugih
uporabnikov. [4]
Ukaz (Primer 2.37), s katerim dovolimo osebi Jaka Kekec, da dostopa in vstavlja v tabelo
student.
GRANT SELECT, INSERT
ON studentje
TO Jaka Kekec;
Primer 2.37 Sintaksa uporabe GRANT ukaza
Z REVOKE (Primer 2.38) izničimo pravice uporabnika na določenih podatkovnih
objektih. [2] [4]
REVOKE pravice
ON ime_objekta
FROM {ime_uporabnika |PUBLIC |ime_skupine};
Primer 2.38 Sintaksa REVOKE ukaza
S pravicami onemogočimo uporabniku upravljanje z določenimi tabelami, ti ukazi so
ALL, EXECUTE, SELECT, INSERT, UPDATE, DELETE, REFERENCES, ALERT in
INDEX.
Ime_objekta je objekt podatkovne baze, ta je lahko TABLE, VIEW, STORED PROC ali
SEQUENCE.
Ime_uporabnika je uporabnik, kateremu se odvzamejo te pravice.
Ime_skupine pomeni, da odvzamemo pravice neki skupini uporabnikov. [4]
Priporočila za pisanje SQL stavkov Stran 23
Ukaz (Primer 2.39), s katerim osebi Jaka Kekec odvzamemo pravice dostopa in vstavljanja
podatkov v tabelo student.
REVOKE SELECT, INSERT
ON studentje
FROM Jaka Kekec;
Primer 2.39 Sintaksa uporabe REVOKE ukaza
2.12 Pogledi (angl. view)
SQL nam omogoča pogled že shranjenih podatkov. Pogled ali angleško view je shranjen v
podatkovni bazi kot virtualna tabela, njegova vsebina pa je definirana v enem od
povpraševanj. Uporabnik jo vidi kot realno tabelo. SQL ustvari iluzijo pogleda, tako da
določi pogledu ime, kot je ime tabele ter shrani definicijo pogleda v podatkovno bazo.
Je pomemben del SQL-a, ker nam omogoča upravljanje pogleda podatkovne baze, tako da
jo uporabniki vidijo iz različnih pogledov. Prav tako nam omogoča, da omejimo dostop do
podatkovne baze. Uporabnikom pa omogočimo pogled samo določenih tabel, stolpcev ali
celic ter poenostavi dostop do podatkovne baze preko struktur shranjenih podatkov na
najbolj enostaven način za uporabnika. [2]
Pogled s seboj prinaša številne prednosti.
Varnost: vsak uporabnik ima dostop do podatkovne baze skozi majhno skupino
pogledov, ki vsebuje specifične podatke, za katere je pooblaščen uporabnik. Takšna je
omejitev uporabnika, za dostop do shranjenih podatkov.
Preprostost povpraševanja: pogled združi podatke iz več različnih tabel in jih predstavi
kot enojno tabelo, pretvori tudi več-tabelno povpraševanje v eno-tabelno.
Konstrukcijska preprostost: pogled omogoča uporabniku lasten pogled strukture
podatkovne baze in predstavitev podatkovne baze kot skupino virtualnih tabel.
Ločitev od sprememb: pogled lahko predstavi nespremenjeno sliko strukture
podatkovne baze, tudi če so spodnje tabele razdeljene, preimenovane ali
prestrukturirane. Definicija pogleda se mora posodobiti vsakokrat, ko se s strani
pogleda preimenuje spodnja tabela ali stolpec.
Integriteta podatkov: če so podatki dostopni preko pogleda, lahko SUPB avtomatsko
preveri podatke in zagotovi, da so podatki pod pritiskom specifične integritete. [2]
Priporočila za pisanje SQL stavkov Stran 24
Vsaka stvar vsebuje tako dobre kot slabe strani, tako ima tudi pogled nekaj slabosti.
Predstavitev: pogled ustvari tabelo, vendar mora SUPB prevesti povpraševanja iz
pogleda, v povpraševanja spodnjih tabel. Če je pogled definiran z kompleksnim
povpraševanjem iz več tabel, potem enostavno povpraševanje proti pogledu postane
zapleten stik tabel in zahteva veliko več časa za dokončanje. Vsako slabo strukturirano
povpraševanje lahko privede do problemov s predstavitvijo.
Upravljanje sposobnosti: pogled mora biti urejen. Če imajo razvijalci in uporabniki
podatkovne baze dovoljenje za ustvarjanje pogledov brez kontrol ali standardov,
postane delo podatkovne baze zelo zapleteno. Več kot je plasti med izvornimi tabelami
in pogledom, toliko težje je rešiti probleme pripisane pogledom.
Omejitev posodobitev: ko želi uporabnik posodobiti vrstico pogleda, mora SUPB
prevesti zahtevo kot posodobitev vrstice izvornih spodnjih tabel. To je mogoče samo za
preproste poglede, bolj kompleksni pogledi pa so namenjeni samo branju (angl. read-
only). [2]
Priporočila za pisanje SQL stavkov Stran 25
3 PRIPOROČILA ZA PISANJE POVPRAŠEVANJ SQL
Iz več različnih SQL povpraševanj lahko na koncu dobimo iste rezultate. Vendar je
pomembno kako bomo prikazali te rezultate in katero povpraševanje bomo uporabili, da
bomo pri tem porabili čim manj časa za izvajanje in nam bo dolgoročno predstavljal
najbolj optimalno izbiro glede porabe virov podatkovne baze in možnosti sprememb
oziroma nadgradnje. To pa imenujemo optimizacija SQL povpraševanj.
3.1 Procesiranje SQL stavkov
Preden začnemo z optimizacijo SQL stavkov, moramo poznati shemo procesiranja.
Za izvajanje SQL povpraševanja pri procesiranju proces uporablja pretvornik oziroma
parser, ki opravlja z sintaktično in semantično analizo SQL stavkov. Uporablja tudi
optimizator, ki deluje z notranjimi pravili ali metodami na osnovi vrednotenja za določanje
najbolj učinkovite poti proizvajanja rezultatov povpraševanja.
Izhod optimizatorja je načrt, ki opisuje optimalne metode izvajanja. Poznamo dve metodi,
optimizator na osnovi pravil (angl. rule-based optimizer; RBO) in optimizator na osnovi
vrednotenja (angl. cost-based optimizer; CBO). Za izvajanje je pomemben generator izvora
vrstic, ki prejme optimalen načrt od optimizatorja in proizvede izvedbeni načrt za SQL
stavke. Kot izhod nam poda načrt izvajanja SQL stavkov.
Izvedbeni načrt je zbirka virov vrstic, ki so razvrščeni v drevesno strukturo. In na koncu
uporabi še SQL izvedbeni stroj, ki deluje na izvedbenem načrtu združenem s SQL stavki in
proizvede rezultate povpraševanja. Vsako vrstico, ki je bila generirana z generatorjem
vrstic, se da izvršiti s SQL izvedbenim strojem. [14] [15]
Iz slike, ki prikazuje proces SQL-a (Slika 3.1) je razvidno, da ko uporabnik zažene SQL
povpraševanje, gre to naprej do pretvornika oziroma parserja, kateri posreduje
povpraševanje do optimizatorja, katerega vhod temelji na osnovi pravil ali vrednotenju. Če
Priporočila za pisanje SQL stavkov Stran 26
uporabi vhod na osnovi vrednotenja CBO, ta pridobi statistiko od podatkovnega slovarja.
Načrt povpraševanja, ki je bil generiran z optimizatorjem, se posreduje generatorju izvora
vrstic, nato se izvede SQL in šele na koncu se pridobljeni rezultati vrnejo do uporabnika.
[14]
Slika 3.1 Proces SQL-a [14]
Cilj osnovanega optimizatorja na vrednotenju CBO je prepustnost. Kar pomeni, da izbere
zadnjo vrednost sredstev za proces vseh vrstic. Prav tako lahko optimizira stavek z
najhitrejšim odzivnim časom, saj uporablja zadnjo vrednost za proces prvih vrstic. Takšen
pristop optimizatorja se uporablja predvsem za novejše metode in lastnosti, kar je razvidno
iz njegove arhitekture (Slika 3.2), kjer imamo razčlenjeno povpraševanje, ki vstopa v
preoblikovalca povpraševanj. Preoblikovano povpraševanje se pošlje do ocenjevalnika.
Statistiko dobimo iz slovarja in nato se povpraševanje in ocenjevalnik skupaj pošljeta do
generatorja načrtov. Na koncu generator načrtov pošlje načrt do ocenjevalnika ali pa napoti
načrt povpraševanja h generatorju izvora vrstic.
Priporočila za pisanje SQL stavkov Stran 27
Pristop na osnovi pravil RBO, pa se uporablja pretežno za združitev s starejšimi
aplikacijami. Iz tega je razvidno, da je boljše uporabiti CBO optimizator.
Slika 3.2 CBO arhitektura [14]
Preoblikovalec povpraševanj kot vhod dobi razčlenjeno povpraševanje. Njegova glavna
naloga je, da se odloči ali je koristno spreminjati povpraševanje. To stori tako, da omogoči
generator izboljševanja načrta povpraševanja. Poznamo štiri različne tehnike
preoblikovanja: združevanje pogledov, pritisk predikata, ne preizkušanje vgnezdenih
povpraševanj in reportaža povpraševanj s pomočjo materializiranih pogledov.
Povpraševanje lahko uporablja kakršne koli kombinacije teh preoblikovanj.
Ocenjevalnik generira tri različne ukrepe: selektivnost, kardinalnost in vrednost. Naloga
selektivnosti je, da označi vrstice, katere bodo prišle skozi test predikata. Kardinalnost
Priporočila za pisanje SQL stavkov Stran 28
predstavlja število vrstic v sklopu vseh vrstic. Poznamo več tipov kardinalnosti: efektivno
(angl. effective), stik (angl. join), razlika (angl. distinct) in skupinsko kardinalnost.
Vrednost predstavlja enote dela ali porabo virov pri operaciji. CBO uporablja za delo disk
vhodno/izhodno enoto (angl. I/O; Input/ Output), centralno procesno enota (angl. CPU;
Central Processor Unit) in spomin. Kot operacija je lahko kopiranje tabele, dostop vrstic s
pomočjo indeksov, stik dveh tabel ali sortiranje vrstic. Glavna naloga generatorja načrtov
je, da preizkusi več načrtov na že obstoječih povpraševanjih in na koncu izbere tistega, ki
ima najnižjo vrednost. Možnih je več načrtov zaradi različnih kombinacij, kot so dostopne
poti, metode stikov tabel in vrstni red stikov, iz katerih lahko dobimo iste rezultate. Število
možnih načrtov je v sorazmerju s številom stikov v FROM stavku. Torej če se poveča
število stikov, se prav tako poveča število možnih načrtov. Prav zaradi tega generator
načrtov uporablja notranje rezanje za zmanjšanje teh načrtov in poišče tistega z najnižjo
vrednostjo. Notranji rez temelji na vrednosti trenutnega najboljšega načrta. [14] [15]
Slika (Slika 3.3) prikazuje faze za izvajanje SQL stavkov. V določenih primerih lahko
nekateri programi za upravljanje z podatkovnimi bazami te korake izvajajo v drugačnem
vrstnem redu.
Slika nam prikazuje posamezne faze SQL procesiranja za vsak posamezen tip SQL stavka.
[16]
Priporočila za pisanje SQL stavkov Stran 29
Slika 3.3 Faze procesiranja SQL stavkov [16]
Priporočila za pisanje SQL stavkov Stran 30
3.2 Optimizacija celotnega postopka SQL-a
Pred optimizacijo moramo najprej narediti tudi naslednje (Slika 3.4):
Slika 3.4 Celotna optimizacija [23]
Vedno najprej začnemo s SQL optimizacijo na nivoju sistema, če tega ne storimo, nam
lahko kasnejše spremembe razveljavijo že optimizirane izvedbene načrte.
Optimizacija jedra strežnika: optimizirati moramo naš disk in omrežje vhod/izhod
(angl. I/O, Input/Output), da lahko nato optimiziramo vhodni/izhodni čas, velikost
omrežnih paketov in poslane frekvence.
Prilagoditev statistike našega optimizatorja: vedno zbiramo in shranjujemo statistiko
optimizatorja, s tem optimizatorju dovolimo da poizve več o porazdelitvi podatkov za
izbiro najboljšega izvedbenega načrta. Prav tako lahko histogram hitro spremeni SQL,
in sicer v primeru ugotovljene rešitve optimalnega stika tabel in ob dostopu na
asimetričnih WHERE stavkih.
Priporočila za pisanje SQL stavkov Stran 31
Prilagoditev parametrov optimizatorja: lastnost_optimizatorja,
predpomnenje_indeksov_optimizatorja, optimizator_indeks_cena_prid.
Optimizacija primera: naša izbira pb_velikost_vrstic, pb_velikost_predpomnjenja in
parametri operacijskega sistema lahko vplivajo na analizo zmogljivosti SQL-a.
Optimizacija preobremenitve SQL dostopa s fizičnimi indeksi in materializiranimi
pogledi: SQL preobremenitev moramo vedno optimizirati z indeksi, še posebno tiste na
katere se sklicujejo funkcije.
Ko so okolje, primeri in objekti optimizirani, se lahko posvetimo tistemu najbolj
pomembnemu vidiku, optimiziranju podatkovne baze in optimizaciji posameznih SQL
stavkov. [23]
3.3 Optimizacija SQL povpraševanj
Preden začnemo z optimizacijo si moramo postaviti nekaj vprašanj in na njih odgovoriti.
Dobro moramo poznati naslednje:
Sistem za upravljanje s podatkovno bazo, na katerem bomo izvajali optimizacijo.
Podatkovni model in aplikacijo, iz katerih bomo črpali SQL stavke in jih optimizirali.
Čas trajanja izvajanja posameznega SQL stavka in njegovo mejo porabe podatkov. Pri
tem si lahko pomagamo z analizo trajanja povpraševanj ali pa sami določimo najdaljši
čas izvajanja.
Ali so naša testiranja optimiziranih stavkov enaka kot na realnih podatkih? Kajti lahko
se razlikuje število podatkov v podatkovni bazi, pri tem ko je velikost in razmerje
polnitve tabel drugačno kot na realnih podatkih. Zaradi tega moramo izvesti
optimizacijo še na podatkih podatkovne baze, katera je namenjena za dejansko
uporabo.
Če se bo okolje, v katerem se nahaja SQL stavek, ki ga želimo optimizirati
spreminjalo. Če se bodo spremenili podatki v podatkovni bazi, ali kakšen drug del
aplikacije, se moramo zamisliti, ali se bo lahko naš optimiziran stavek prilagajal tem
spremembam. Zaradi tega moramo zasnovati čim bolj transparenten stavek. [24]
Šele ko smo seznanjeni s temi vprašanji in dejstvi lahko, začnemo z optimizacijo.
Priporočila za pisanje SQL stavkov Stran 32
Od programov pričakujemo, da se odzivajo hitro. Če programiramo na internetu ali na
strežniku, nam podatkovna baza vrne rezultat pri katerih je odzivni čas daljši. Tudi ko
uporabljamo hitrejše strežnike, je odzivni čas vedno odvisen od algoritma katerega
uporabljamo, tako da nam ne preostane drugega kot optimizacija povpraševanj. Ker pa se
povpraševanja po navadi izvajajo zelo hitro, tudi če vsebujejo več stikov tabel, sortiranje
ali kalkulacije, se to zgodi prej kot v sekundi. Tako po navadi optimiziramo vsa
povpraševanja, ki nimajo izvajalni čas daljši od ene sekunde. Najboljše je, če optimiziramo
povpraševanja, ki se največkrat pojavljajo in tista, ki imajo daljši čas izvajanja.
Sprva preverimo celotno podatkovno bazo, povezave med tabelami in ali je podatkovna
baza normalizirana. Nato iz povpraševanja izločimo vse vrstice, ki jih ne potrebujemo za
izvajanje. Če imamo stike tabel, te uporabljamo zelo previdno, kajti stik uporabimo samo
med tistim tabelami, kjer jih resnično potrebujemo ter samo na indeksiranih poljih. V
nasprotnem primeru pride do nepotrebne izgube časa pri izvajanju. Pri povpraševanjih,
kjer pregledamo skozi vse tabele, nam k optimizaciji veliko pripomore pravilna uporaba
indeksov in primarnih ključev. Vsak primarni ključ mora vsebovati indeks, saj nam to v
primeru stika tabel omogoča hitrejše izvajanje. Prav tako mora vsaka tabela vsebovati
primarni ključ. V primeru, da imamo v povpraševanjih veliko polj, ki se ponavljajo, je
priporočljivo, da nanje v tabeli nastavimo indekse. Prav tako za hitrejše izvajanje
največkrat se ponavljajoča povpraševanja shranimo kot shranjeni postopek (angl. SP
Stored Procedure). To je SQL stavek, ki je že shranjen v podatkovni bazi, kar pa je
vsekakor hitrejše, kajti shranjen je na samem strežniku od kjer se izvaja potem tudi samo
povpraševanje. Tudi mi prihranimo pri času, saj nam ni potrebno vedno znova pisati
enakih povpraševanj. Odstranimo poglede (angl. view), ki jih ne potrebujemo, ker so
posebni tipi povpraševanja in niso tabele. Pogled je virtualna tabela in se izvaja tako rekoč
povpraševanje v povpraševanju, kar pa je seveda počasnejše od izvajanja samo enega
povpraševanja. Prav tako nam k hitrejšemu izvajanju veliko pripomore sama optimizacija
podatkovne baze.
Poznamo več orodij, ki so nam v pomoč pri optimizaciji SQL povpraševanj. [11]
Priporočila za pisanje SQL stavkov Stran 33
3.4 Metode in tehnike pisanja optimiziranih SQL povpraševanj
1. Izbira najboljše gonilne tabele (angl. Driving table)
To je prva tabela pri stiku tabel, ki nam poda najmanjše število vrstic in porabi najmanj
virov. SUPB poveže dve tabeli, tako da najprej sortira prvo tabelo (gonilno tabelo) in nato
drugo tabelo ter poveže prebrane vrstice obeh tabel. S tem bomo skrajšali čas in olajšali
izvajanje SQL povpraševanja.
Če uporabljamo RBO optimizator je ta vrstni red zelo pomemben, kajti stavki se izvajajo
od desne proti levi. Zato je najboljše, da gonilno tabelo napišemo zadnjo.
Če pa uporabljamo CBO optimizator, vrstni red tabel ni pomemben. Namesto tega se
uporablja statistika in podatkovni slovar za določitev gonilne tabele. [17]
Kot lahko na spodnjemu primeru (Primer 3.1) vidimo, je v tem primeru gonilna tabela
tabela smeri. Pri tem zajamemo in pregledamo celotno vrstico tabele smeri, ob tem pa se v
tabeli studentje poiščejo vrstice, ki ustrezajo iskanju. V primeru, da bi imeli indeks
nastavljen samo na tabeli studentje in ne na tabeli smeri, bi kot gonilno tabelo uporabili
tabelo studentje. [18]
SELECT *
FROM studentje s, smeri r
WHERE r.id_smeri = s.id_smeri;
Primer 3.1 gonilne tabele
2. Vrstni red tabel v stavku FROM
Kot smo že omenili zgoraj v 1. točki, je pomembno po katerem vrstnem redu zapišemo
tabele v stavku FROM, še posebej če imamo več tabel. Pregledovalnik namreč bere tabele
od desne proti levi. Zaradi tega moramo gonilno tabelo napisati zadnjo, da se potem lahko
izvede prva, ali pa tisto, ki je najmanjša.
3. Vrstni red pogojev v WHERE stavku
Vrstni red pogojev v WHERE stavku ocenimo po naslednjih kriterijih: največjo prednost
imajo vgnezdena povpraševanja, ta imajo prednost pred zunanjimi boolean pogoji. Zadnji
po kriteriju so vsi boolean pogoji brez vgrajenih funkcij ali vgnezdenih povpraševanj, ki
Priporočila za pisanje SQL stavkov Stran 34
so v WHERE stavku, pri čemer se zadnji predikat ovrednoti kot prvi. V naraščajoči vrstni
red glede na njihovo ocenjeno vrednost pa so uvrščeni boolean predikati z vgrajenimi
funkcijami.
Problem pri tem je, da lahko optimizator preuredi vrstni red zaradi bolj optimalnega
izvedbenega načrta. Pri tem pa imamo lahko dva različna pogleda glede razvrščanja
pogojev. In sicer se ta vrstni red popolnoma razlikuje, če želimo optimizirati vhod/izhod ali
če želimo optimizirati centralno procesno enoto. [19]
4. Izvajanje SQL povpraševanja je hitrejše, če v SELECT stavku napišemo imena
stolpcev (Primer 3.2), namesto da uporabimo znak * za izbiro vseh stolpcev v tabeli
(Slika 3.5). [4]
Manj primerno Bolj primerno SELECT *
FROM studentje;
SELECT id_studenta, ime_in_priimek,
vpisna_stevilka, starost, povprecna_ocena, status,
letnik
FROM studentje;
Primer 3.2 povpraševanj za hitrejše izvajanje
Slika 3.5 Rezultat povpraševanja za hitrejše izvajanje
Priporočila za pisanje SQL stavkov Stran 35
5. HAVING stavek se uporablja za filtriranje podatkov, ko so izbrane vse vrstice (Primer
3.3). Za vse ostale namene, pa ga raje ne uporabimo. [4]
Manj primerno (Slika 3.6) Bolj primerno (Slika 3.7) SELECT naziv_smeri, count
(naziv_smeri)
FROM smeri
GROUP BY naziv_smeri
HAVING naziv_smeri != 'ITK'
AND naziv_smeri != 'RIT';
SELECT naziv_smeri, count
(naziv_smeri)
FROM smeri
WHERE naziv_smeri != 'ITK'
AND naziv_smeri != 'RIT'
GROUP BY naziv_smeri;
Primer 3.3 pravilne uporabe HAVING stavka
Slika 3.6 Rezultat HAVING povpraševanja
Slika 3.7 Rezultat HAVING povpraševanja
6. Imamo čim manj vgnezdenih povpraševanj v osnovnem povpraševanju (Primer 3.4)
(Slika 3.8).
Manj primerno Bolj primerno SELECT ime_in_priimek
FROM studentje
WHERE povprecna_ocena =
(SELECT MIN (povprecna_ocena)
FROM studentje)
AND letnik =
(SELECT MIN (letnik)
FROM studentje)
AND starost = 22;
SELECT ime_in_priimek
FROM studentje
WHERE (povprecna_ocena, letnik) =
(SELECT MIN (povprecna_ocena),
MIN (letnik)
FROM studentje)
AND starost=22;
Primer 3.4 vgnezdenega povpraševanja
Priporočila za pisanje SQL stavkov Stran 36
Slika 3.8 Rezultati vgnezdenega povpraševanja
7. Operatorje EXISTS, IN in stik tabel uporabimo takrat, ko je to primerno (Primer 3.5,
Slika 3.9).
Operator IN ima najpočasnejše izvajanje. Najbolj učinkovita uporaba operatorja IN pa je
takrat, ko se večina filtriranih kriterijev nahaja v vgnezdenem povpraševanju. Najbolj
učinkovita uporaba operatorja EXISTS je takrat, ko se večina filtriranih kriterijev nahaja v
glavnem povpraševanju. [4]
Manj primerno Bolj primerno SELECT *
FROM fakultete f
WHERE id_fakultete
IN
(SELECT id_fakultete
FROM smeri s);
SELECT *
FROM fakultete f
WHERE EXISTS
(SELECT *
FROM smeri s
WHERE s.id_fakultete=f.id_fakultete);
Primer 3.5 EXISTS, IN in stik tabel
Slika 3.9 Rezultati EXSIST povpraševanja
Priporočila za pisanje SQL stavkov Stran 37
8. Ko uporabimo stik tabel, ki vsebujejo relacijo ena proti mnogo ( 1 : m ), namesto
ukaza DISTINCT uporabimo EXISTS (Primer 3.6). Ker ukaz DISTINCT nam vrne samo
tiste vrednosti, ki se razlikujejo.
Manj primerno (Slika 3.10) Bolj primerno (Slika 3.11) SELECT DISTINCT f.id_fakultete,
f.naziv
FROM fakultete f, smeri s
WHERE s.id_fakultete =
f.id_fakultete;
SELECT f.id_fakultete, f.naziv
FROM fakultete f
WHERE EXISTS
(SELECT *
FROM smeri s
WHERE s.id_fakultete =
f.id_fakultete);
Primer 3.6 ukaza DISTINCT in EXISTS
Slika 3.10 Rezultati DISTINCT ukaza
Slika 3.11 Rezultati EXISTS ukaza
9. Namesto ukaza UNION raje uporabimo UNION ALL (Primer 3.7, Slika 3.12). [4]
Manj primerno Bolj primerno SELECT ime_in_priimek,
povprecna_ocena
FROM studentje
UNION
SELECT naziv_smeri,
stevilo_letnikov
FROM smeri;
SELECT ime_in_priimek,
povprecna_ocena
FROM studentje
UNION ALL
SELECT naziv_smeri,
stevilo_letnikov
FROM smeri;
Primer 3.7 ukaza UNION in UNION ALL
Priporočila za pisanje SQL stavkov Stran 38
Slika 3.12 Rezultati UNION povpraševanja
10. Previdno uporabimo pogoje v WHERE stavku (Primer 3.8). [4]
Manj primerno Bolj primerno WHERE starost != 22; WHERE starost > 22;
WHERE
SUBSTR(ime_in_priimek,1,3)='Dia';
WHERE ime_in_priimek LIKE 'Dia%';
WHERE ime = NVL (:ime,
ime_studenta);
WHERE ime
LIKE NVL (:ime, '%');
WHERE povprecna_ocena >=
MAX (povpecna_ocena)
AND povprecna_ ocena <=
MIN (povprecna_ocena);
WHERE povprecna_ocena
BETWEEN
MAX (povprecna_ocena)
AND MIN (povprecna_ocena);
WHERE naziv || postna_stevilka
='Laško3270';
WHERE naziv ='Laško'
AND postna_stevilka= 3270;
Primer 3.8 WHERE stavkov
11. Izjave pišemo v WHERE stavku, samo na eni strani povpraševanja zaradi hitrejšega
izvajanja (Primer 3.9).
Manj primerno Bolj primerno WHERE povprecna_ocena * 10 < 100 ; WHERE povprecna_ocena < 100;
WHERE starost NOT = 22; WHERE starost > 22;
Primer 3.9 WHERE stavkov
Priporočila za pisanje SQL stavkov Stran 39
12. Da se izognemo kopiranju istih vrstic ali stiku istih tabel, uporabimo ukaz DECODE
(Primer 3.10). Prav tako lahko ta ukaz uporabimo namesto GROUP BY ali ORDER BY
stavka. [4]
Manj primerno (Slika 3.13) Bolj primerno (Slika 3.14) SELECT DECODE (status, 'DA',
id_studenta, NULL) id_studenta
FROM studentje
WHERE ime_in_priimek
LIKE 'Dia%';
SELECT id_studenta
FROM studentje
WHERE ime_in_priimek
LIKE 'Dia%'
AND status = 'DA';
Primer 3.10 DECODE ukaza
Slika 3.13 Rezultati DECODE ukaza
Slika 3.14 Rezultati povpraševanja
13. Če hočemo shranjevati velike binarne objekte, te najprej shranimo v sistemski datoteki
in nato to datoteko dodamo v podatkovno bazo. [4]
14. Če hočemo napisati povpraševanje, ki nam zagotavlja učinkovito predstavitev
podatkov, moramo slediti napotkom, da uporabimo enojne primere za vse SQL ukaze.
Vsak SQL ukaz začnemo pisati v novi vrstici. Besede v povpraševanju med seboj ločimo z
enojnim presledkom. Za ukaze znotraj začetnega SQL ukaza, je najboljše da jih poravnamo
levo ali desno. [4]
15. Ne smemo pozabiti, da NULL ni enak praznemu stringu in tudi ne številu 0. [12]
Priporočila za pisanje SQL stavkov Stran 40
16. Če v povpraševanju uporabimo več tabel, je najboljše da te tabele preimenujemo in
nadalje uporabimo vzdevke tabel (Primer 3.11) (Slika 3.15).
SELECT s.ime_in_priimek, n.stalni_naslov
FROM studentje s, naslovi n
WHERE s.id_naslova = n.id_naslova;
Primer 3.11 vzdevki tabel
Slika 3.15 Rezultati vzdevkov tabel
17. V WHERE stavku primerjamo niz z nizom in število s številom (Primer 3.12, Slika
3.16). [12]
Manj primerno Bolj primerno SELECT id_studenta, ime_in_priimek
FROM studentje
WHERE id_studenta = '73';
SELECT id_studenta, ime_in_priimek
FROM studentje
WHERE id_studenta = 73;
Primer 3.12 primerjava v WHERE stavku
Slika 3.16 Rezultati WHERE povpraševanja
Priporočila za pisanje SQL stavkov Stran 41
18. Če je mogoče, uporabimo ne pretvorjene vrednosti stolpcev (Primer 3.13). [12]
Manj primerno Bolj primerno WHERE SUBSTR (s.id_smeri,
INSTR(t.id_smeri, ',')-1)=
SUBSTR (t.id_smeri,
INSTR(t.id_smeri, ',')-1);
WHERE s.id_smeri = t.id_smeri;
Primer 3.13 ne pretvorjene vrednosti
19. Če moramo uporabiti SQL funkcije v stikih tabel, tega raje ne storimo na indeksiranih
stolpcih.
20. RETURNING stavek
INSERT, UPDATE ali DELETE RETURNING uporabimo, ko je to najbolj primerno.
S tem zmanjšamo klice k podatkovni bazi.
21. Priporočljivo je uporabiti CASE stavke (Primer 3.14).
Bolj učinkovito je, če izvajamo enojno povpraševanje kot dva ločena, da dobimo enak
rezultat.
Manj primerno Bolj primerno SELECT COUNT (1)
FROM studentje
WHERE povprecna_ocena < 10; SELECT COUNT (1)
FROM studentje
WHERE povprecna_ocena
BETWEEN 7 AND 9;
SELECT COUNT (CASE WHEN
povprecna_ocena < 10
THEN 1 ELSE null END) count_1,
COUNT (CASE WHEN povprecna_ocena
BETWEEN 7 AND 9
THEN 1 ELSE null END) count_2,
FROM studentje;
Primer 3.14 CASE stavka
22. Uporabimo rownum ukaz. Ta se uporablja za filtriranje rezultatov povpraševanja,
vendar lahko povzroči slabšo predstavitev. Poznamo tudi nekaj pravil pri katerih
uporabimo naslednje ukaze.
Najboljša povpraševanja: rownum se lahko uporabi za materializiranje vrstičnega
pogleda.
Priporočila za pisanje SQL stavkov Stran 42
Območje omejenih povpraševanj: poznamo posebne primere, pri katerih je pametno
uporabiti rownum za hitrejše izvajanje povpraševanj.
DML (podatkovno manipulacijski jezik angl. data manipulation language): v nekaterih
primerih lahko uporabimo rownum z DML, toda samo v primeru ko nameravamo
narediti posodobitev, da uporabimo indeks z indeks namigom. [20]
3.5 Koraki optimiziranja
Skoraj vsak problem, ki se pojavi pri SQL izvedbi, se da razrešiti. Edina razlika med njimi
je, da so nekateri problemi kompleksnejši kot drugi. Popravki vključujejo naslednje
aktivnosti:
Analizo tabel, da pridobimo informacije katere potrebuje naša aplikacija, ki jo
uporabljamo za učinkovito rešitev SQL-a.
Dodajanje namigov SQL-u za spodbujanje ali zatiranje izvedljivih načrtov.
Manjše spremembe na SQL-u za spodbujanje ali zatiranje izvedljivih načrtov.
Restrikcijo slabo načrtovanega SQL-a, ki se jih ne da učinkovito rešiti.
Spremembo strukture. Npr. dodajanje ali spreminjanje indeksov; vstavljanje skupin,
particij ali indeksov – organizirane tabele; denormalizacija tabel; uporaba uresničljivih
pogledov.
Posredovanje problema administratorju podatkovne baze. Pri tem imamo rešitev, ki
vključuje primer optimizacije, rekonstrukcijo ali premik prostora v tabeli ali arhiviranje
starih podatkov.
Posredovanje problema administratorju sistema. Pri tem imamo rešitev, ki vključuje
rekonfiguracijo ali obstoječo strojno opremo ali pridobitev nove strojne opreme.
Vsak problem, ki se pojavi je različen od drugega. Rešitev tega je logični proces predhodne
podrobne analize.
Obstajajo trije osnovni koraki optimiziranja.
1. Izločimo problem iz ostalega SQL-a v svoj SQL.
Če ne vemo, katero od povpraševanj je počasno, lahko to ugotovimo na več načinov.
Priporočila za pisanje SQL stavkov Stran 43
Če je problem ustvaril določen uporabnik in ta traja minuto ali več, lahko ob pojaviti tega
problema, to sporočimo avtorju povpraševanja. Da ugotovimo, katero povpraševanje se
trenutno izvaja lahko ugotovimo s pomočjo ukaza SQL * Text. To je enostavna SQL koda,
ki nam prikaže vsa SQL povpraševanja, ki se izvajajo za določen UporabnikovId, Server
Pid in KlientId. Ali pa uporabimo Oracle Trace, da sledimo njihovemu celotnemu poteku
povpraševanja. Ko je problem izločen iz povpraševanja in nam SQL * Text, ni bil v
pomoč, potem bomo morali slediti celotnemu poteku izvajanja povpraševanj od začetka do
konca. Če je aplikacija na splošno počasna, ali pa je vzrok nenavadna preobremenitev na
glavnem računalniku, potem za izločitev problema potrebujemo pomoč administratorja
podatkovne baze (angl. DBA data base administrator). Najboljše je, da uporabimo program
za sledenje celotni podatkovni bazi.
2. Analiziramo SQL, da ugotovimo problem.
Preden začnemo analizirati problem preverimo, ali imamo na razpolago hitre popravke
(angl. quick fix), kar pomeni da odkrijemo vsakdanje SQL probleme, ki jih lahko hitro
prepoznamo in popravimo. Prav tako moramo poznati probleme hranjenja podatkov (angl.
Data storage). Če nam ta dva napotka ne koristita, moramo analizo nadaljevati. Pri tem
lahko naletimo na še dva pomembnejša problema, majhen obseg SQL-a (angl. Low volume
SQLs ) in velik obseg SQL-a (angl. High volume SQLs). Od majhnega obsega SQL-a se
pričakuje, da prebere samo nekaj vrstic in dostopa do tabele preko indeksov. Pri tem
nastane problem, saj če manjka indeks, se ignorira ali je napačno uporabljen. Velik obseg
SQL-a je po navadi poročilo ali serija nalog in če te vsebujejo indekse, lahko ta zelo trpi.
Pri tem je bolj koristno, če preberemo celotno tabelo, kot da bi uporabili indekse. Torej, če
procesiramo nekaj več procentov tabele, ki ima več kot deset tisoč vrstic, raje uporabimo
pregled celotne tabele (angl. Full table scan). Poleg osnovnih problemov, ki se pojavijo pri
velikem obsegu SQL-a, poznamo tudi bolj specifične, ki se pojavijo pri velikem obsegu
podatkovno manipulacijskega jezika (angl. High volume DML), npr. imamo v
povpraševanju ukaz INSERT, UPDATE ali DELETE, ki morajo pri izvajanju pregledati
veliko število vrstic. Če imamo ukaz DELETE ali dodamo primarni ali sekundarni ključ
moramo sprva preveriti, da tabele na katere se sklicujemo v stavkih nimajo tujih ključev.
In probleme, ki se pojavijo pri SQL procesu (angl. Procedural SQL), npr. če uporabljamo
Priporočila za pisanje SQL stavkov Stran 44
SQL jezik ali kakšen drug proceduralni jezik, pri katerem imamo narejeno zanko in pri tem
zasega veliko podatkov.
3. Popravimo problem.
Če naš problem še vseeno ni razrešen, preverimo, če so naša pričakovanja realistična in ali
imamo povpraševanje napisano po napotkih, ki so navedeni v poglavju 3.4. [13]
3.6 Pripomočki za optimiziranje SQL povpraševanj
Eden od takih programov je Oraclov SQL Query Analyzer. Osnovno okno v programu je
tisto, s katerim ustvarjamo SQL povpraševanja in optimiziramo (Slika 3.17). Prikaže nam
podatkovno bazo, sejo, SQL povpraševanje in razlagalni načrt. Okno vsebuje navigacijsko
ploščo in podokno za SQL tekst in podokno podrobnosti. [11]
Slika 3.17 SQL Query Analyzer
Priporočila za pisanje SQL stavkov Stran 45
Navigacijska plošča (Slika 3.18) nam prikazuje drevesno strukturo kazala vozlišč, objektov
in SQL povpraševanj. Prav tako nam zagotavlja dostop do strežnikov podatkovne baze,
katere povpraševanja lahko optimiziramo.
Slika 3.18 Navigacijska plošča
Podokno za SQL tekst (Slika 3.19) nam kot seznam prikaže izbrana vsa povpraševanja in
tista, ki so bila izbrana preko vrha SQL-a (angl.TopSQL) in zgodovine SQL-a (angl. SQL
History) (Slika 3.20). Prav tako lahko ta povpraševanja tudi urejamo.
Slika 3.19 Podokno za SQL tekst
Slika 3.20 Podokno za SQL tekst z uporabo TopSQL in SQL History
Priporočila za pisanje SQL stavkov Stran 46
Podokno podrobnosti (Slika 3.21) nam poda informacije o izbranem povpraševanju,
vključenih razlagalnih načrtih, lastnostih objektov in statistiko zmogljivosti.
Slika 3.21 Podokno podrobnosti
Namen SQL Query Analyzer-ja je sortiranje SQL povpraševanj po metriki izvajanja in
vrnitev podrobnih podatkov o optimizaciji podanega povpraševanja. Pri tej SQL
metodologiji optimizacije pomagata ukaza SQL namig (angl. SQL Hint) in čarovnik za
optimizacijo SQL-a (angl. SQL Tuning wizard ). [21]
Čeprav je najboljša prednost SQL-ja fleksibilnost, kar pomeni da ne glede na to kateri
pristop izberemo lahko dobimo isti rezultat. Izvedba pa je odvisna od podatkovnega okolja,
strukture indeksov in poti dostopa, katero določi Oraclov optimizator. Pri optimizaciji
lahko nekatera povpraševanja povzročijo počasno izvajanje, kajti v velikih primerih se
Priporočila za pisanje SQL stavkov Stran 47
zgodi, da naše izvajanje doseže sam vrh zmogljivosti, to je 100 % ali več. Optimizacija ni
enostavna, ker vključuje zbiranje in analizo podatkov ter zahteva od nas dobro poznavanje
tega področja in izkušnje. Polega tega zahteva zavedanje trenutnega podatkovnega okolja
in podatkov, poznavanje vseh objektov sheme, razumevanje delovanja Oraclovega
optimizatorja in podrobno znanje SQL-a. Oracle SQL Analyzer nam omogoča zbiranje
podatkov o podatkovnem okolju in objektih sheme, analizo SQL izvajanja, prepoznavanje
in primerjavo različnih pristopov optimizacije in urejanje SQL povpraševanj za optimalno
izvajanje. To se zgodi v nekaterih primerih samodejno.
Prednosti SQL Query Analyzerja
Zagotavlja nam funkcionalnosti za odkrivanje tistih SQL povpraševanj, ki porabijo
največ sredstev.
Zagotavlja nam dostop do zgodovine SQL povpraševanj, ki so se že izvajala nad
podatkovno bazo.
Zagotavlja nam izvedbo SQL-a pod različnimi načini optimizatorja in nam predstavi
razlagalne načrte ter statistiko izvajanja za enostavno primerjavo.
Analyzer nas vodi skozi izvedbeni načrt, zagotavlja nam vrstni red izvajanja in razlago
operacij.
Po posameznih korakih nas vodi skozi analizo SQL povpraševanj in njenih
potencialnih stikih ter metodah, ob tem pa nam poda alternativo za izboljšanje
izvajanja.
Samodejno preveri SQL povpraševanje za morebitne kršitve oblike SQL stavkov ter
generira alternativo za popravilo teh.
Predstavi nam tudi pomembne objekte lastnosti za pomoč odkrivanja in popravilo
problemov, ki vpliva na SQL izvajanje.
Zagotavlja nam enostaven dostop inicializacije parametrov, ki imajo direkten vpliv na
izvajanje.
S pomočjo čarovnika za namige, nam omogoča dodajanje namigov k povpraševanju.
SQL povpraševanja, izvedbene načrte in statistiko predstavitve nam shrani v tako
imenovano skladišče iz katerega jih je mogoče kasneje uporabljati.
Priporočila za pisanje SQL stavkov Stran 48
Zagotovi nam priporočila indeksov za izboljšanje predstavitve.
Proces SQL optimizacije preko SQL Query Analyzerja poteka v štirih stopnjah.
Najprej začnemo s SQL sejo, pri tem imamo na voljo kar nekaj načinov kako začeti z
optimizacijo. Določimo lahko povpraševanja, ki se izvajajo oziroma se bodo izvajala na
podatkovni bazi. Začnemo s tistimi, ki so bila izbrana s pomočjo vrha SQL-a ali so
shranjena v SQL zgodovini. Ustvarimo lahko tudi novo povpraševanje oziroma vstavimo
že obstoječe v SQL Query Analyzer. Če nam je lažje, lahko odpremo SQL datoteko v
Analyzerju in preuredimo povpraševanje ali pa gremo nazaj na SQL povpraševanje iz
prejšnje seje optimiziranja ter uredimo prejšnjo sejo optimizacije.
Nato začnemo z zbiranjem informacij, tu imamo na izbiro dva načina, kako začeti. Ob
vpogledu v inicializacijo parametrov lahko izvemo več o optimizacijskem okolju. Če pa bi
radi več izvedeli o zmogljivosti SQL povpraševanja, moramo zgenerirati razlagalni načrt.
Pogled skozi ta načrt nam bo pojasnil, kako je povpraševanje izvedeno. Ob primerjavi
našega razlagalnega načrta z ostalimi načrti, zberemo informacije o statistiki zmogljivosti
in lastnosti objektov, kot so tabele, grozdi, indeksi in pogledi … vrstni red stikov urejenih z
optimizerjem, stopnjo vzporednosti in porazdelitev.
Potem je na vrsti optimizacija SQL povpraševanja, te lahko urejamo ročno ali uporabimo
čarovnika namigov (angl. Hint Wizard) za dodajanje namigov, ki definirajo pristop
optimizacije za SQL povpraševanje, cilj pristopa optimizacije SQL povpraševanja, ki
temelji na vrednotenju, dostopno pot do tabel, ki imajo dostop preko povpraševanj in vrstni
red stikov za povpraševanje, ki vsebuje stike tabel. Uporabimo lahko čarovnika za
optimizacijo SQL-a (angl. SQL Tuning Wizard) za pomoč pri optimizaciji do najboljše
zmogljivosti. Pomaga nam dodati namige povpraševanja, uporabljati smernice SQL
sintakse (angl. rules-of-thumb) in meriti učinkovitost optimizacije prizadevanja ob
primerjavi optimiziranega povpraševanja z originalnim. Ali pa pridobimo priporočila, SQL
Query Analyzer nam bo zagotovil priporočila in SQL scenarij, ki ga lahko uporabimo za
implementacijo predlaganih sprememb.
Na koncu pa izvedemo še preverjanje naših rezultatov, tu lahko uporabimo iste metode kot
pri zbiranju informacij, da preverimo ali se je zmogljivost povpraševanja izboljšala. To pa
Priporočila za pisanje SQL stavkov Stran 49
lahko naredimo tako, da izvršimo novo povpraševanje in primerjamo rezultate, ustvarimo
nov razlagalni načrt in ga primerjamo s prejšnjimi ali pregledamo lastnosti objektov in
zagotovimo da so točni. [22]
Priporočila za pisanje SQL stavkov Stran 50
4 SKLEP
Nenehno spreminjanje in dodajanje podatkov v podatkovno bazo zahteva optimizacije.
Tudi če imamo dobro izgrajen podatkovni model, »slabo« napisanih SQL povpraševanj,
kar slabo vpliva na aplikacijo. Če imamo veliko povpraševanj, vendar je samo eno od njih
slabo grajeno, ima aplikacija lahko zelo počasno izvajanje. Prav zaradi tega je cenejše in
enostavnejše če ta povpraševanja optimiziramo, kot pa da bi ves čas skrbeli, da imamo
najsodobnejšo opremo.
S pomočjo diplomskega dela smo spoznali, kako pomembna je optimizacija, še posebno
optimiziranje SQL povpraševanj. Spoznali smo tudi proces optimizacije povpraševanj ter
pisanje preprostejših stavkov s hitrejšim izvajalnim časom. Vedno moramo že v naprej
razmišljati, kako se bomo lotili optimizacije, da si bomo olajšali delo. Poleg tega je seveda
pomembno, da si pred delom ustvarimo načrt in si postavimo vprašanje kaj bi pravzaprav
radi dobili kot rezultat in katere pomembne dejavnike moramo pri tem upoštevati.
Pomembno je da si sproti shranjujemo vse kar naredimo, kajti tako lahko med seboj
primerjamo razne izvedbene načrte ali pa sama povpraševanja in ob spremembi lažje
ugotovimo, kaj se je spremenilo in kako to vpliva na aplikacijo. Preden pa dokončno
uporabimo povpraševanja v zaključenih aplikacijah moramo to dobro stestirati tudi na
realnih primerih, da kasneje ne bi imeli težav z aplikacijo.
Poleg optimizacije SQL povpraševanj, ki je podrobneje opisana v diplomskemu delu, je
pomembno da predhodno dobro načrtujemo in optimiziramo tudi druge elemente, ki so
pomembni za uspešno delovanje končne aplikacije: npr. optimizacija podatkovne baze,
dobro načrtovan entitetno-relacijski podatkovni model, primerne normalizacije, itd.
Priporočila za pisanje SQL stavkov Stran 51
5 VIRI
[1] Welzer Družovec Tatjana: Predavanja, Podatkovne baze
[2] James R. Groff, Paul N. Weinberg, Andrew J. Oppel: SQL The Complete Reference,
Third Edition, The McGraw-Hill Companies, 2010
[3] http://msdn.microsoft.com/en-us/library/h09t6a82(v=vs.80).aspx [8.5.2012].
[4] http://beginner-sql-tutorial.com [8.5.2012].
[5] http://docs.oracle.com/html/A95915_01/sqopr.htm#i1004871 [8.5.2012].
[6] http://www.w3schools.com/sql/ [8.5.2012].
[7] Gints P. : SQL set operators, 2008. Dostopno na:
http://www.gplivna.eu/papers/sql_set_operators.htm#p2.4 [8.5.2012].
[8] http://www.1keydata.com/sql/sql-exists.html [8.5.2012].
[9] Haertzen D. http://infogoal.com/sql/sql-syntax.htm [8.5.2012].
[10] http://www.techonthenet.com/oracle/functions/decode.php [8.5.2012].
[11] http://www.serverwatch.com/tutorials/article.php/2175621/How-to-Optimize-Queries-
Theory-an-Practice.htm [8.5.2012].
[12] http://www.sql-performance-tuning.com/oracle-sql-performance-tuning/ [8.5.2012].
[13] http://www.orafaq.com/tuningguide/ [8.5.2012].
[14] http://docs.oracle.com/cd/B10500_01/server.920/a96533/optimops.htm#76553
[8.5.2012].
[15] http://courses.csusm.edu/cs643yo/slides/optimization.htm [8.5.2012].
[16] http://docs.oracle.com/cd/A57673_01/DOC/server/doc/A48506/sqlconce.htm
[8.5.2012].
[17] http://www.dba-oracle.com/t_driving_table.htm [8.5.2012].
[18]http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:19281234807
2 [8.5.2012].
[19] http://www.dba-oracle.com/Oracle_tips_sql_predicate_order.htm [8.5.2012].
[20] http://www.dba-oracle.com/t_sql_tuning_rownum_equals_one.htm [8.5.2012].
Priporočila za pisanje SQL stavkov Stran 52
[21] http://docs.oracle.com/html/A86647_01/parthree.htm [30.5.2012].
[22] http://docs.oracle.com/html/A86647_01/vmqintro.htm [30.5.2012].
[23] http://www.dba-oracle.com/art_sql_tune.htm [8.5.2012]
[24] Paznik M. Optimizacija podatkovne baze: Pravila optimizacije SQL stavkov. Maribor:
Fakulteta za elektrotehniko, računalništvo in informatiko Univerze v Mariboru, 2003.
Dostopno na: http://dkum.uni-mb.si/Dokument.php?id=6432 [8.5.2012].
Priporočila za pisanje SQL stavkov Stran 53
Priporočila za pisanje SQL stavkov Stran 54
Priporočila za pisanje SQL stavkov Stran 55