Query optimization

Transcript

Query optimization
Ottimizzazione di interrogazioni
Tecnologie delle Basi di Dati M
Ottimizzazione delle query
• Come visto, la risoluzione di un’interrogazione
(anche semplice) può essere realizzata
in diversi modi, con costi differenti
• Per ogni query, il DBMS deve scegliere
il modo migliore (più veloce) per risolverla
• A tal fine il query manager dispone di
un ottimizzatore e di un valutatore dei piani
di accesso
2
Funzionamento dell’ottimizzatore
• L’ottimizzazione di una query richiede:
• L’enumerazione dei possibili piani di accesso
per la sua risoluzione
• La stima del costo di ogni piano di accesso, al fine
di selezionare il piano dal costo minore (stimato)
• La stima del costo di ogni piano di accesso
viene effettuata dal valutatore dei piani
di accesso usando le statistiche fornite
dai cataloghi
3
Esempio di ottimizzatore: DB2
•
•
•
•
•
Parse query
Check semantics
Rewrite query
Optimize access plan
Generate executable
code
• Il tutto si basa su
un modello di query
a grafo
• Nodi = operatori
• Archi = dati
4
Parsing e check semantico
• Il primo passo consiste nel verificare la validità
lessicale e sintattica della query (parsing)
• Al termine di questo passo viene prodotta una
prima rappresentazione interna, che evidenzia gli
oggetti interessati (relazioni, attributi, ecc.)
• La fase di check semantico, facendo uso dei
cataloghi, verifica che:
• Gli oggetti referenziati esistano
• Gli operatori siano applicati a dati di tipo opportuno
• L’utente abbia i privilegi necessari per eseguire
l’operazione
5
Riscrittura di query
• Ha lo scopo di semplificare la query da
ottimizzare
• Tipiche attività:
• Risoluzione di viste
• Trasformazione di subquery in join
• Eliminazione di join ridondanti
(ad es. derivati da altre riscritture)
• Spostamento/eliminazione di DISTINCT
• Pushdown dei predicati
• Trasformazione OR/IN
6
Risoluzione di viste
• Per un semplice esempio, si consideri la vista:
CREATE VIEW EmpSalaries(EmpNo,Last,First,Salary)
AS
SELECT EmpNo,LastName,FirstName,Salary
FROM Employee
WHERE Salary > 20000
e la query:
SELECT Last, First
FROM EmpSalaries
WHERE Last LIKE ‘B%’
• La risoluzione della vista porta a riscrivere la
query come: SELECT LastName,FirstName
FROM
Employee
WHERE Salary > 20000
AND
LastName LIKE ‘B%’
7
Interrogazioni
Sistemi Informativi L-B
Query innestate
• Le subquery sono query SELECT usate
nella clausola WHERE di un’altra query
• Una subquery si dice correlata se fa riferimento
ad attributi (“variabili”) delle relazioni nel blocco
“esterno”, altrimenti è detta costante
• In genere, si producono piani di accesso
per le subquery come se fossero query a parte
• Per evitare però di “perdere” dei piani di accesso
a basso costo, l’ottimizzatore cerca di riscrivere
la query senza usare subquery
8
Unnesting: esempio I
• Il passaggio a una forma senza subquery
alle volte è immediato; ad esempio la
seguente query:
SELECT EmpNo, PhoneNo
FROM Employee
WHERE WorkDept IN ( SELECT DeptNo
FROM
Department
WHERE DeptName = ‘Operations’ )
viene riscritta come:
SELECT EmpNo, PhoneNo
FROM Employee E, Department D
WHERE E.WorkDept = D.DeptNo
AND
D.DeptName = ‘Operations
9
Interrogazioni
Sistemi Informativi L-B
Unnesting: esempio II
• La query:
SELECT E.EmpNo
FROM
Employee E
WHERE E.EmpNo NOT IN ( SELECT EA.EmpNo
FROM Emp_Act EA )
viene riscritta usando un outer join:
SELECT Q.EmpNo
FROM ( SELECT E.EmpNo, EA.EmpNo
FROM Emp_Act EA RIGHT OUTER JOIN Employee E
ON (E.EmpNo = EA.EmpNo) ) AS Q(EmpNo,EmpNo1)
WHERE Q.EmpNo1 IS NULL
10
Interrogazioni
Sistemi Informativi L-B
Uso dei vincoli (i)
• Il DBMS “ragiona” sfruttando la presenza di
vincoli per semplificare le query.
• Ad esempio, se EmpNo è una chiave:
SELECT DISTINCT EmpNo
FROM Employee
la query si riscrive più semplicemente come:
SELECT EmpNo
FROM
Employee
11
Interrogazioni
Sistemi Informativi L-B
Uso dei vincoli (ii)
• Per un esempio di semplificazione basata sul
vincolo di Foreign Key, si consideri:
SELECT EA.EmpNo
-- EA.EmpNo FK
FROM
Emp_Act EA
WHERE EA.EmpNo IN (SELECT EmpNo FROM Employee)
che viene riscritta come:
SELECT EA.EmpNo FROM
Emp_Act EA
• Se EA.EmpNo ammettesse valori nulli, la
riscrittura aggiungerebbe
WHERE EA.EmpNo IS NOT NULL
12
Interrogazioni
Sistemi Informativi L-B
Uso dei vincoli (iii)
• Si supponga di avere la vista:
CREATE VIEW People
AS
SELECT FirstName,LastName,DeptNo,MgrNo
FROM Employee E, Department D
WHERE E.WorkDept = D.DeptNo
e: SELECT LastName,FirstName FROM People
in cui chi esegue la query non ha privilegio di
SELECT né su Employee né su Department
• Il DBMS può però semplificare la query:
SELECT LastName,FirstName FROM Employee
eventualmente con WorkDept IS NOT NULL
13
Interrogazioni
Sistemi Informativi L-B
Modello interno della query
• Rappresentazione ad albero:
• Foglie = relazioni
• Nodi interni = operatori dell’algebra
psnome
• Rami = flussi di dati
svid=100val>4
• Radice = risultato dell’interrogazione
sid=sid
SELECT S.snome
FROM Recensioni R, Sommelier S
Recensioni Sommelier
WHERE R.sid=S.sid
AND R.vid=100 AND S.val>4
psnome(svid=100val>4(Recensionisid=sidSommelier))
14
Piano di accesso
• L’ottimizzatore trasforma l’albero della query in
un albero di operatori fisici, ognuno dei quali è
• un algoritmo che realizza un operatore dell’algebra
• un metodo di accesso alle relazioni
psnome
psnome
Sul momento
svid=100val>4
svid=100val>4
Sul momento
sid=sid
sid=sid
Recensioni
Sommelier
File scan Recensioni
Page nested loops
Sommelier
File scan
15
Esecuzione di piani di accesso
• Per eseguire un piano di accesso occorre valutare
gli operatori dell’albero a partire dal basso
• Esistono due possibilità di esecuzione
• Per materializzazione
• Ogni operatore memorizza il proprio risultato in una tabella
temporanea
• Un operatore a livello più alto deve attendere che tutti gli operatori
di input abbiano terminato l’esecuzione per iniziare a produrre
il proprio risultato
• In pipeline (tramite iteratori)
• Ogni operatore richiede un risultato agli operatori di input
• Non è “bloccante”
• Non sempre è possibile (es. sort)
16
Esecuzione per materializzazione (i)
SELECT
FROM
WHERE
AND
P.ProjNo, E.EmpNo, D.*
Department D,Employee E,Project P
E.WorkDept = D.DeptNo
E.EmpNo = P.RespEmp
E.WorkDept = D.DeptNo
E.EmpNo = P.RespEmp
17
Esecuzione per materializzazione (ii)
• L’esecuzione per materializzazione produrrebbe come
risultato del primo Join:
A partire da tale risultato intermedio si può
poi calcolare il secondo join
18
Esecuzione in pipeline: esempio
• Si inizia a eseguire il primo join
• La prima tupla prodotta:
viene subito passata in input al secondo join,
che inizia la ricerca di matching tuples
e produce la prima tupla del risultato:
• L’esecuzione prosegue cercando eventuali altri match
per la tupla prodotta dal primo join; quando è
terminata la scansione della relazione interna
(Department), il secondo join richiede al primo di
produrre un’altra tupla
• …
19
Esecuzione in pipeline
• Per semplificare il codice di coordinamento
dell’esecuzione dei piani di accesso si usa
un’interfaccia standardizzata per gli operatori:
• Metodi:
• open: inizializza, alloca buffer, passa parametri e
richiama open sui figli
• hasNext: verifica se ci sono altre tuple
• next: prende la prossima tupla
• reset: riparte dalla prima tupla (es. nested loops)
• close: termina e rilascia le risorse
20
Piani di accesso alternativi (i)
• Supponiamo di eseguire l’albero visto
psnome
in precedenza:
Sul momento
• Il costo risulta quello
svid=100val>4
Sul momento
del join: 501000 I/O
sid=sid
Page nested loop
ovvero circa 1.4 ore!
• Potremmo fare peggio Recensioni Sommelier File scan
• Prodotto Cartesiano tra le relazioni seguito
dalla selezione sull’attributo di join
• Vogliamo cercare di ridurre il costo evitando
di valutare tutte le possibili alternative
21
Piani di accesso alternativi (ii)
• Poiché il join è un’operazione costosa, una prima
soluzione è diminuire la dimensione degli input
• Una possibilità è quella di applicare le selezioni prima
di effettuare il join (push-down)
• Es.: vid=100 si applica solo a Recensioni
Sul momento
• Creiamo relazioni temporanee T1 e T2 psnome
e le ordiniamo
sid=sid
Merge-scan
• Costo = P(R) + P(T1) + P(S) + P(T2)
+ sort(T1) + sort(T2) + P(T1) + P(T2) Sort
Sort
=1000 + 10 + 500 + 250
sval>4 Scan
Scan svid=100
+ 40 + 1500 + 10 + 250
= 3560 (35 sec)
Recensioni Sommelier
22
Piani di accesso alternativi (iii)
• Un’altra possibilità è quella di introdurre
una proiezione in quanto, per il join e in output,
solo sid e snome sono richiesti
psnome
Sul momento
• Si riducono le dimensioni
delle tabelle temporanee
sid=sid
Page nested loop
• Es.: possiamo usare
page nested loops
psid,snome Sul momento
Sul momento psid
• Costo = P(R) + P(T1’)
+ P(S) + P(T2’)
sval>4 Scan
Scan svid=100
+ P(T1’) + P(T2’) =
1000 + 3 + 500 + 250 + 3 + 250 Recensioni Sommelier
= 2006
(20 sec)
23
Piani di accesso alternativi (iv)
• La presenza di indici può ridurre ulteriormente
il costo
p
snome
Sul momento
• Es.: supponiamo di avere
sval>4
un indice hash su R.vid
Sul momento
ed uno su S.sid
sid=sid
Index nested loop
• Possiamo usare
Index scan
index nested loops
svid=100 Sommelier
• Costo = L(R) + f x N(R) x 1 =
10 + 1000 = 1010 (10 sec) Recensioni
• La selezione su S.val non può essere pushed
(perché?)
24
Modifica dei piani di accesso
• È evidente che, nella riscrittura di un piano
di accesso, occorre che l’ottimizzatore
non modifichi la semantica della query originale
• Occorre conoscere l’equivalenza di espressioni
in algebra relazionale (con NULL e duplicati)
•
•
•
•
•
Raggruppamento e commutatività della selezione
Raggruppamento e commutatività della proiezione
Commutatività e associatività del join
Push-down della selezione sul join
…
25
Stima del costo di un piano di accesso
• Per ogni nodo dell’albero fisico occorre stimare:
• Il costo
• Si usano le stime già viste, tenendo conto che il pipelining
permette di risparmiare il costo di scrittura delle relazioni
temporanee in uscita
• La dimensione del risultato
• Se il risultato è ordinato o meno
• Il tutto si basa su statistiche che vengono
mantenute aggiornate (dal DBMS/DB admin)
26
Esempio: le statistiche di DB2
• Come sappiamo, le statistiche di DB2
vengono mantenute all’interno dei cataloghi
• Schema SYSSTAT
• Le statistiche vengono aggiornate tramite il
comando RUNSTATS
• È possibile iniziare l’aggiornamento delle statistiche
sia manualmente che automaticamente
• Vengono mantenute statistiche su tabelle,
indici, colonne, distribuzioni, gruppi di colonne
27
Esempio: statistiche su tabelle
• FPAGES
• Pagine usate da una tabella
• NPAGES
• Pagine contenenti record (≤ FPAGES)
• CARD
• Record in una tabella (cardinalità)
28
Esempio: statistiche su colonne
• COLCARD
• Cardinalità dell’attributo
• AVGCOLLEN
• Dimensione media dell’attributo
• HIGH2KEY, LOW2KEY
• Secondo valore maggiore/minore dell’attributo
• NUMNULLS
• Numero di valori null
• … e altro ancora
29
Esempio: statistiche su indici
• NLEAF
• Foglie
• NLEVELS
• Livelli (altezza)
• CLUSTERRATIO
• Grado di clusterizzazione dei dati rispetto all’indice
• DENSITY
• Percentuale di foglie memorizzate sequenzialmente
• NUMRIDS
• RID memorizzate nell’albero
30
Stima del numero di valori distinti
• E’ spesso necessario conoscere il numero di
valori distinti di un attributo (o combinazione di
attributi)
• L’approccio basato su sorting richiede
O(P log P) per ogni attributo
• Esiste un metodo (molto) più veloce basato su
hashing, noto come linear counting, che ha
complessità O(P)
31
Linear counting
• Si predispone in RAM un array di B bit, inizialmente
tutti a 0
• Si scandisce la relazione R e, per ogni tupla r, si
applica una funzione hash H a valori in [0,B-1] al
valore dell’attributo A di interesse,
• Si pone B[H(r.A)] = 1
• Al termine si conta il numero Z di bit rimasti a 0
• Si stima il numero di valori distinti di A, NK(R.A):
NK(R.A)  B ln (B/Z)
32
Linear counting: analisi
• Basata sullo stesso modello della formula di Cardenas
• Poiché il numero di duplicati di ogni valore non ha
influenza su Z, si ha che in media vale la relazione:
B – Z = B (1-(1-1/B)NK)  B – B e-NK/B
e quindi: Z  B e-NK/B  ln(Z/B)  - NK/B
 NK  B ln (B/Z)
• Perché il metodo funzioni occorre garantire Z > 0
• Ad es., ponendo B = N
• Il metodo è ovviamente applicabile a più attributi, o
combinazioni, in parallelo
33
Istogrammi
• Il solo numero di valori distinti può portare a stime
poco accurate, che possono quindi influenzare in
modo impredicibile il processo di ottimizzazione
• Es.: Dati N dipendenti e NK(ruolo) ruoli:
• quanti dipendenti hanno il ruolo ‘operaio’? N/NK(ruolo) (?)
• quanti ‘direttore di filiale’? N/NK(ruolo) (?)
• La distribuzione uniforme è spesso (molto) lontana
dalla realtà dei dati
• Vale anche per domini numerici
• Praticamente tutti i DBMS si basano su istogrammi
per ottenere stime più accurate
34
Tipi di istogrammi
Equi-width: il dominio viene suddiviso in B intervalli della
stessa ampiezza
• Non offrono garanzie sull’errore che si può commettere
Equi-depth: il dominio viene suddiviso in B intervalli, in
modo che il numero di tuple in ogni intervallo sia
(circa) lo stesso
• Migliori, ma sensibili ai valori molto frquenti
Compressed: come equi-depth, ma per ognuno dei
V valori più frequenti viene mantenuto un contatore
separato
• Spesso usati nei DBMS (anche in DB2)
35
Tipi di istogrammi: esempio
• La distribuzione delle N=45 tuple, con NK=15 valori distinti, è:
10
9
8
8
6
4
2
3
3
1
2
2
4
3
4
2
1
0
2
1
0
Equi-width (B=5):
20
15
1
15
15
10
2
3
4
5
6
7
8
9
10
8
5
10
3
12
13
14
15
Equi-depth (B=5):
15
4
11
12
9
9
9
10-14
15-15
6
5
0
1-3
4-6
7-9
10-12
13-15
0
12
10
9
10
9
8
9
8
1-4
5-7
8-9
Compressed (B=3, V=2)
6
4
2
0
1-4
5-9
10-14
8
15
36
Query su singola relazione
• Se la query contiene un’unica relazione
nella clausola FROM dobbiamo valutare solo
proiezioni e selezioni (+ eventuali
raggruppamenti ed operazioni aggregate)
• Ci sono 4 possibili soluzioni
•
•
•
•
Scansione sequenziale
Uso di un solo indice (eventualmente clustered)
Uso di più indici
Uso solo di un indice (non si accede ai dati)
37
Esempio (i)
SELECT rivista
FROM Recensioni
WHERE vid=417 and anno>2005
• Esistono un indice hash su vid, un B+-tree
su anno ed uno su (vid, anno, rivista)
Scansione sequenziale
• Si leggono tutte le pagine e si effettuano selezione
e proiezione sul momento
• Costo = P(R)
38
Esempio (ii)
Uso di un solo indice
• L’indice più selettivo è quello su vid
• Si leggono i record tramite le RID fornite dall’indice
• Viene valutato il predicato su anno ed effettuata
la proiezione su rivista
Uso di più indici
• Si usano sia l’indice su vid che quello su anno
• Le RID ottenute vengono intersecate
• Si leggono i record e si effettua la proiezione
Uso solo di un indice
• Si usa l’indice composto
39
L’ottimizzatore DB2: predicati (i)
• I predicati nell’ottimizzatore DB2 sono
di 4 tipi (in ordine di efficienza decrescente):
• Range-delimiting
• Delimitano il range di foglie dell’indice cui accedere
• Index SARGable
• Non delimitano il range di foglie, ma sono utilizzabili se si
accede tramite indice
Es: indice: A,B,C; A=5  C>10: C>10 è index SARGable
• Data SARGable
• Utilizzabili all’istante dell’accesso ai dati
• Residual
• Es.: subquery correlate, ANY, ALL, …
40
L’ottimizzatore DB2: predicati (ii)
• La tabella riassume gli effetti dei 4 tipi di
predicati
RangeIndex
delimiting SARGable
Data
SARGable
Residual
Riduzione
Index I/O
Sì
NO
NO
NO
Riduzione
Data I/O
Sì
Sì
NO
NO
Riduzione
num. tuple
Sì
Sì
Sì
NO
Riduzione
output finale
Sì
Sì
Sì
Sì
41
L’ottimizzatore DB2: metodi di accesso
• Ci sono 3 modi per accedere ad una tabella:
• Scansione sequenziale
• Scansione tramite indice (B+-tree)
• Scansione tramite lista di RID ottenuta per unione o
intersezione (ma non entrambe) da 2 o più indici
• L’accesso tramite indice può avvenire per:
• Test di: IS (NOT) NULL, disuguaglianza,
uguaglianza con una costante, …
• Ordinamento
42
Query su più relazioni
• In questo caso è necessario effettuare join
delle N relazioni coinvolte
• Esistono 2N  1!  N! 2N  1 1 modi diversi
N  1!
 N  1  N


di effettuare il join (includendo i prodotti
cartesiani) tra N relazioni
(=permutazioni x num. modi di “mettere le parentesi”)
• 2 su 2 relazioni
12 su 3 relazioni
• 120 su 4 relazioni
1680 su 5 relazioni
• 30240 su 6 relazioni
665280 su 7 relazioni
• 17297280 su 8 relazioni
43
Query su più relazioni: N = 3
• I 12 possibili modi sono
•
•
•
•
•
•
(R1  R2)  R3
(R2  R1)  R3
(R1  R3)  R2
(R3  R1)  R2
(R2  R3)  R1
(R3  R2)  R1
•
•
•
•
•
•
R1  (R2  R3)
R2  (R1  R3)
R1  (R3  R2)
R3  (R1  R2)
R2  (R3  R1)
R3  (R2  R1)
44
Determinazione del piano ottimale
• L’ottimizzatore dispone di una strategia di
enumerazione dei piani di accesso, i cui compiti
principali sono:
• Enumerare tutti i piani che, potenzialmente,
possono risultare ottimali
• Non generare piani di accesso che sicuramente
non possono risultare ottimali
45
Spazio di ricerca
• Lo spazio dei possibili piani di accesso è, tipicamente,
molto vasto (esponenziale in N):
• Ogni operatore può essere realizzato in più modi
• Ogni query può essere riscritta in più modi diversi
• Possono esistere diverse strutture che agevolino
l’accesso ai dati
• Per questo motivo, in genere vengono applicate
regole euristiche per ridurre lo spazio di ricerca
• L’ottimo non è garantito ma si trova una soluzione valida
in tempo ragionevole
• Diversi DBMS permettono di controllare esplicitamente
i tipi di piani considerati
46
Left-deep trees
• Una scelta comune è usare solamente left-deep
trees, ovvero alberi di join in cui il figlio destro
di un nodo è sempre una relazione del DB
• Gli altri alberi si chiamano bushy
• Si scartano gli alberi che comportano l’esecuzione
di prodotti cartesiani
• Il figlio destro è la relazione interna (che è
obbligatoriamente materializzata)
• In questo modo è possibile sempre generare piani
in pipeline
• Soluzione usata in System R
47
Esempio
SELECT S.snome, V.vnome, R.anno
FROM Sommelier S, Recensioni R, Vini V
WHERE S.sid=R.sid AND R.vid=V.vid
AND R.rivista=“Sapore DiVino”
• Le possibili sequenze di join sono solo 4
(=12 – 6 bushy -2 con prodotti cartesiani):
•
•
•
•
(R  S)  V
(S  R)  V
(R  V)  S
(V  R)  S
48
Proprietà di piani di accesso
• Ogni nodo di un piano di accesso può anche essere
visto come la radice di un piano di accesso (“parziale”
o “completo”)
• Ogni piano di accesso ha delle proprietà:
•
•
•
•
•
•
•
Costo
Cardinalità
Schema (set di attributi)
Relazioni
Predicati applicati
Ordine
….
Proprietà di un nodo = f(prop. figli,op. nodo)
49
Ordini significativi
• L’ordine delle tuple di un nodo è detto significativo se
può influenzare le operazioni ancora da compiere
(o il risultato finale)
SELECT S.snome, R.rivista, V.cantina
FROM Recensioni R, Sommelier S, Vini V
WHERE R.sid=S.sid AND R.vid=V.vid
AND V.vnome=‘Merlot’
ORDER BY S.snome,V.cantina
• Dopo il join tra V e S, gli ordini significativi sono:
• sid (può influenzare il join con R)
• snome (semplifica l’ORDER BY)
• snome, cantina (risolve l’ORDER BY)
ma non cantina o vid
50
Pruning di piani parziali
• La seguente osservazione è alla base della
determinazione efficiente del piano ottimale:
Un piano di accesso (parziale) AP per i relazioni R1,
R2, …, Ri, il cui risultato è ordinato secondo un ordine
O e il cui costo è maggiore di quello di un piano AP’
per le stesse relazioni e con lo stesso ordine (o più
significativo), non può essere esteso in un piano di
accesso a costo minimo
• Si dice che AP’ “domina” AP
• Le proprietà di AP’ dominano quelle di AP
51
Pruning: esempio I
• La query include ORDER BY R.B
AP
224
AP
546
AP
1127
Cost
345
Cost
216
Cost
234
Cardinality 25
Cardinality
25
Cardinality 25
Schema
{R.A,R.B,S.C}
Schema
{R.A,R.B,S.C}
Schema
{R.A,R.B,S.C}
Tables
{R,S}
Tables
{R,S}
Tables
{R,S}
Predicates R.J=S.J, R.A > 5
Predicates
R.J=S.J, R.A > 5
Predicates R.J=S.J, R.A > 5
Order
Order
none
Order
R.B
R.B
• AP1127 domina AP224, che viene eliminato
• AP546 non domina AP1127, perché non è
ordinato (mentre AP 1127 lo è)
52
Pruning: esempio II
• Ipotesi: si usa solo nested loops e non c’è
nessun ordine significativo
• no ORDER BY, no GROUP BY, no DISTINCT, …
• Per una query sulle relazioni R1, R2 e R3,
supponiamo che per eseguire il join tra R1 e R2
sia più conveniente avere R1 esterna
• Nessun piano con la sequenza
(R2  R1)  R3 può essere ottimale
53
Algoritmo di programmazione dinamica
Livello 1: determina per ogni Ri e ogni ordine
significativo O (incluso il caso non ordinato) il
piano parziale migliore
Livello i (2..N): Per ogni O e ogni sottoinsieme di i
relazioni determina il piano parziale migliore, a
partire dal risultato del passo i-1
Livello N+1: determina il piano di accesso
ottimale, aggiungendo se necessario il costo di
ordinamento finale del risultato
• Il numero di piani valutati è O(2N)
54
Generazione di piani di accesso
• L’algoritmo descritto opera in modo breadth-first (per
“livelli” = num. relazioni considerate)
• In pratica la generazione di nuovi piani procede in
maniera più efficace, tipicamente espandendo i piani
di accesso parziali più “promettenti” (tipicamente:
costo minore)
• Questo normalmente permette di eliminare un
maggior numero di piani parziali
• Si estende di conseguenza il concetto di dominazione:
• Perché AP’ domini AP va anche verificato che le relazioni
elaborate da AP’ includano quelle elaborate da AP
eguaglianza  inclusione
55
Esempio di generazione PdA (i)
SELECT S.snome, R.rivista
FROM Recensioni R, Sommelier S
WHERE R.sid=S.sid
AND R.vid=100 AND S.val=4
• Sono disponibili indici B+-tree unclustered su R.vid,
R.sid, S.val e S.sid
• Gli unici algoritmi di join disponibili sono
il nested loop e l’index nested loop
• N(R)=2000, P(R)=400, NK(R.vid)=100, L(R.vid)=20,
NK(R.sid)=200, L(R.sid)=25
• N(S)=200, P(S)=100, NK(S.val)=20, L(S.val)=3,
NK(S.sid)=200, L(S.sid)=5
56
Esempio di generazione PdA (ii)
• Passo 1: si valuta il metodo di accesso di costo
minimo per ogni relazione
• Non vi sono ordini significativi
• Relazione R:
• Cardinalità risultato = 2000/100 = 20
(AP1) Costo sequenziale = 400
(AP2) Costo indice R.vid = 20/100 +
Φ(2000/100,400)=1+20=21
• Relazione S:
• Cardinalità risultato = 200/20 = 10
(AP3) Costo sequenziale = 100
(AP4) Costo indice S.val = 3/20 + Φ(200/20,100)=1+10=11
57
Esempio di generazione PdA (iii)
• Passo 2: si espande AP4 (costo 11)
considerando il join con R
• Nested loop:
• Costo di partenza = 11
• Costo per ogni loop = 21 (indice R.vid)
(AP5) Costo = 11 + 10 x 21 = 221
• Index nested loop (indice R.sid):
• Costo di partenza = 11
• Costo per ogni loop = 25/200 + Φ(2000/200,400)=1+10 =
11
(AP6) Costo = 11 + 10 x 11 = 121
58
Esempio di generazione PdA (iv)
• Passo 3: si espande AP2 (costo 21)
considerando il join con S
• Nested loop:
• Costo di partenza = 21
• Costo per ogni loop = 11 (indice S.val)
(AP7) Costo = 21 + 20 x 11 = 241
• Index nested loop (indice S.sid):
• Costo di partenza = 21
• Costo per ogni loop = 1 + 1 = 2 (sid chiave di S)
(AP8) Costo = 21 + 20 x 2 = 61
59
Esempio di generazione PdA (v)
• Passo 4: si cerca di espandere AP8 (costo 61)
• Tutti i join sono stati effettuati
• AP8 è il piano di costo minimo
psnome,rivista Sul momento
sid=sid
IndexFilter svid=100
Recensioni
Index nested loop
sval=4
Sul momento
ssid=?
IndexFilter
Sommelier
60
Esempio (i)
SELECT S.snome, R.rivista, V.cantina
FROM Recensioni R, Sommelier S, Vini V
WHERE R.sid=S.sid AND R.vid=V.vid
AND S.val=4 AND V.vnome=‘Merlot’
• Esistono indici B+-tree unclustered su R.sid e R.vid
• Esistono indici B+-tree clustered su S.sid e V.vid
• Si ignorano i costi di accesso agli indici
• N(R)=5000, P(R)=1000, NK(R.sid)=200, NK(R.vid)=100
• N(S)=200, P(S)=100, NK(S.val)=10, NK(S.sid)=200
• N(V)=100, P(V)=20, NK(V.vid)=100, NK(V.vnome)=20
• Ordini significativi: sid, vid
61
Esempio (ii)
• Passo 1: si trovano i metodi di accesso
di costo minimo alle relazioni, conservando anche
quelli che generano ordinamenti utili
(AP1) Scansione di R:
• Costo = 1000, risultati = 5000, ordine: nessuno
(AP2) Indice su R.sid:
• Costo = 5000, risultati = 5000, ordine: sid
(AP3) Indice su R.vid:
• Costo = 5000, risultati = 5000, ordine: vid
(AP4) Scansione di S (con selezione su val):
• Costo = 100, risultati = 200/10 = 20, ordine: sid
(AP5) Scansione di V (con selezione su vnome):
• Costo = 20, risultati = 100/20 = 5, ordine: vid
62
Esempio (iii)
• Passo 2: si espande AP5 (costo 20) considerando
solo il join V  R (V  S è prodotto cartesiano)
• Index nested loop:
• Costo di partenza = 20
• Costo per ogni loop = 5000/100 = 50
(AP6) Costo = 20 + 5 x 50 = 270
• Ordine: vid
• Merge-scan:
• Costo di partenza = 20
• Costo di merge = 5000 (indice unclustered su R.vid)
(AP7) Costo = 20 + 5000 = 5020
• Ordine: vid
• Dimensione risultato = 5000/20 = 250
63
Esempio (iv)
• Passo 3: si espande AP4 (costo 100) considerando
solo il join S  R
• Index nested loop:
• Costo di partenza = 100
• Costo per ogni loop = 5000/200 = 25
(AP8) Costo = 100 + 20 x 25 = 600
• Ordine: sid
• Merge-scan:
• Costo di partenza = 100
• Costo di merge = 5000 (indice unclustered su R.sid)
(AP9) Costo = 100 + 5000 = 5100
• Ordine: sid
• Dimensione risultato = 5000/10 = 500
64
Esempio (v)
• Passo 4: si espande AP6 (costo 270) considerando il
join con S (sequenza: (V  R )  S )
• Index nested loop:
• Costo di partenza = 270
• Costo per ogni loop = 1 (sid chiave di S)
(AP10) Costo = 270 + 250 x 1 = 520
• Sort-merge:
• Costo di partenza = 270
• Costo di sort = 4 x P(temp) (sorting su sid della rel. temporanea)
• Costo di merge = P(temp) + P(temp) + 100
(AP11) Costo = 270 + 4 x 10 + 10 + 10 + 100 = 430
• Dimensione risultato = 250/10 = 25
65
Esempio (vi)
• Passo 5: si cerca di espandere AP11 (costo 430)
• Tutti i join sono stati effettuati
• Questo è il piano di costo minimo, in quanto tutti i piani
parziali sono dominati da AP11
psnome,rivista,cantina Sul momento
sid=sid
Index nested loop
Sul momento
vid=vid
svnome=‘Merlot’ IndexScan svid=?
Scan
Vini
Sort-merge
sval=4 Sul momento
ssid=? IndexScan
Recensioni Sommelier
66
Ricerca greedy
• Talvolta, per diminuire ulteriormente lo spazio
di ricerca, si mantiene per ogni livello
solamente la soluzione a costo minimo o,
a parità di costo, quella che produce il minor
numero di record
• Il costo di ricerca diventa lineare nel numero
delle relazioni coinvolte
• Evidentemente, può portare a perdere
la soluzione migliore
• Attenzione! Per query ad hoc dobbiamo minimizzare il
tempo totale = ottimizzazione + soluzione
67
Esercizio I
• Date le relazioni
Medici(cod, nome, spec)
Pazienti(cod, nome, indirizzo, anno, med)
• N(M)=100, P(M)=5, N(P)=2000, P(P)=100
• Si calcoli il miglior piano di accesso per la query
SELECT P.nome
FROM Medici M JOIN Pazienti P ON (M.cod=P.med)
WHERE M.spec=‘cardiologia’ AND P.anno<1930
• Si supponga di avere indici unclustered su:
• M.spec (L=1, NK=20), M.cod (L=2, NK=100)
• P.anno (L=13, NK=100), P.med (L=13, NK=100)
68
Soluzione (i)
• Fattore di selettività dei predicati:
• M.cod=valore, P.med=valore = 1/100
• M.spec=‘cardiologia’ = 1/20
• P.anno<1930 = 20/100 = 1/5
• Gli ordini da considerare sono
• Medici  Pazienti
• Pazienti  Medici
• La cardinalità del risultato è 2000/(20 x 5) = 20
69
Soluzione (ii)
• Accesso a Medici (esterna):
• Senza indice:
• Costo = P(M) = 5
• Indice su specializzazione:
• Costo = f x L(M.spec) + Φ(f x N(M),P(M))
= 1/20 + Φ(100/20,5) = 1 + 4 = 5
• In entrambi i casi la dimensione del risultato è
f x N(M) = 100/20 = 5
70
Soluzione (iii)
• Accesso a Pazienti (interna):
• Senza indice:
• Costo = P(P) = 100
• Indice su anno:
• Costo = f x L(P.anno) + Φ(f x N(P),P(P))
= 13/5 + Φ(2000/5,100) = 3 + 99 = 102
• Indice su med:
• Costo = f xL(P.med) + Φ(f x N(P),P(P))
= 13/100 + Φ(2000/100,100) = 1 + 19 = 20
• Costo totale = 5 + 5 x 20 = 105
71
Soluzione (iv)
• Accesso a Pazienti (esterna):
• Senza indice:
• Costo = P(P) = 100
• Indice su anno:
• Costo = f x L(P.anno) + Φ(f x N(P),P(P))
= 13/5 + Φ(2000/5,100) = 3 + 99 = 102
• In entrambi i casi la dimensione del risultato è
f x N(P) = 2000/5 = 400
72
Soluzione (v)
• Accesso a Medici (interna):
• Senza indice:
• Costo = P(M) = 5
• Indice su specializzazione:
• Costo = f x L(M.spec) + Φ(f x N(M),P(M))
= 1/20 + Φ(100/20,5) = 1 + 4 = 5
• Indice su cod:
• Costo = 1 + 1 = 2 (cod chiave di M)
• Costo totale = 100 + 400 x 2 = 900
• Il piano migliore è quello con accesso sequenziale
a Medici seguito da un index nested loop join
73
Esercizio II (i)
• Date le relazioni
Clienti(cod, nome, conto), CC(cod, saldo, apertura),
Transazioni(cod, conto, tipo, ammontare)
• N(C)=3K, P(C)=100, N(CC)=2.5K, P(CC)=40 ,
N(T)=100K, P(CC)=3K
• Si calcoli il miglior piano di accesso per la query
SELECT nome
FROM Clienti C JOIN CC ON (C.conto=CC.cod)
JOIN Transazioni T ON (T.conto=CC.cod)
WHERE saldo BETWEEN 5000000 AND 10000000
AND ammontare>1000000
AND tipo=‘versamento’
74
Esercizio II (ii)
• Si supponga di avere indici su:
•
•
•
•
T.tipo (uncl., L=500, NK=25)
T.conto (uncl., L=600, NK=2500)
C.conto (uncl., L=45, NK=2500)
CC.cod (clust., L=50, NK=2500)
• Si supponga di considerare solamente i piani
• CC  Transazioni  Clienti
• Transazioni  Clienti  CC
75
Soluzione (i)
• Fattore di selettività dei predicati:
• CC.saldo = 1/3 (stimata con valore di default)
• T.ammontare = 1/2 (stimata con valore di default)
• T.tipo = 1/25
• Cardinalità del risultato:
•
•
•
•
T che soddisfano i predicati = 100K/50 = 2000
CC che soddisfano il predicato = 2500/3 = 834
CC residui = 834 x 100K/(2.5K x 2 x 25) = 667
Clienti nel risultato = 3000 x 667/2500 = 800
76
Soluzione (ii)
• Valutiamo il piano
CC  Transazioni  Clienti
• Accesso a CC (esterna):
• Senza indice:
• Costo = P(CC) = 40
• La dimensione del risultato è
f x N(CC) = 2500/3 = 834
77
Soluzione (iii)
• Accesso a T (interna):
• Senza indice:
• Costo = P(T) = 3000
• Indice su conto (uncl.):
• Costo = f x L(T.conto) + Φ(f x N(T),P(T))
= 600/2500 + Φ(100000/2500,3000) = 1 + 40 = 41
• Indice su tipo (uncl.):
• Costo = f x L(T.tipo) + Φ(f x N(T),P(T))
= 500/25 + Φ(100000/25,3000) = 20 + 2200 = 2220
• La dimensione del risultato è
834 x f x N(T) = 834 x 100K/(2.5K x 50)
= 667
78
Soluzione (iv)
• Accesso a C (interna):
• Senza indice:
• Costo = P(C) = 100
• Indice su conto (uncl.):
• Costo = f x L(C.conto) + Φ(f x N(C),P(C))
= 45/2500 + Φ(3000/2500,100) = 1 + 2 = 3
• Costo totale = 40 + 834 x 41 + 667 x 3 = 36235
79
Soluzione (v)
• Valutiamo il piano
Transazioni  Clienti  CC
• Accesso a T (esterna):
• Senza indice:
• Costo = P(T) = 3000
• Indice su tipo (uncl.):
• Costo = f x L(T.tipo) + Φ(f x N(T),P(T))
= 500/25 + Φ(100000/25,3000) = 20 + 2200 = 2220
• La dimensione del risultato è
f x N(T) = 100K/50 = 2000
80
Soluzione (vi)
• Accesso a C (interna):
• Senza indice:
• Costo = P(C) = 100
• Indice su conto (uncl.):
• Costo = f x L(C.conto) + Φ(f x N(C),P(C))
= 45/2500 + Φ(3000/2500,100) = 1 + 2 = 3
• La dimensione del risultato è
2000 x f x N(C) = 2000 x 3000/2500 = 2400
81
Soluzione (vii)
• Accesso a CC (interna):
• Senza indice:
• Costo = P(CC) = 40
• Indice su cod (clust.):
• Costo = 1 + 1 = 2 (cod chiave di CC)
• Costo totale = 2220 + 2000 x 3 + 2400 x 2 =
13020
• Il piano migliore è quello con accesso a Transazioni
tramite indice su tipo seguito da un index nested
loop join su Clienti e da un altro
index nested loop join su CC
82
Esercizio III (i)
• Date le relazioni
Personale(cod, mansione, stipendio, proj),
Progetti(cod, consegna, sede, descr)
• N(Pers)=50K, NK(mansione)=1K,
NK(stipendio)=5K, size(Pers)=48B
• N(Proj)=4K, NK(consegna)=365, NK(sede)=100,
NK(descr)=500, size(Proj)=64B
• Si calcolino le dimensioni delle relazioni
per size(pagina) = 4096B, ipotizzando
un fattore di riempimento del 100%
83
Esercizio III (ii)
• Si supponga di avere indici su:
•
•
•
•
•
Personale.cod (uncl., size(cod)=10B)
Personale.mansione (clust., size(mansione)=20B)
Personale.proj (uncl., size(proj)=10B)
Progetti.cod (uncl., size(cod)=10B)
Progetti.consegna (clust., size(consegna)=8B)
• Si calcoli il numero di foglie per ciascun indice,
ipotizzando un fattore di riempimento del 70%
ed una dimensione di 4 byte per ogni RID
84
Esercizio III (iii)
• Infine, si calcoli il miglior piano di accesso
per la query
SELECT *
FROM Personale P JOIN Progetti PR
ON (P.proj=PR.cod)
WHERE PR.sede=‘Roma’ AND PR.consegna
BETWEEN 01/01/2010 AND 31/01/2010
AND P.mansione=‘progettista’
85
Soluzione (i)
• Dimensione di Personale:
• Numero di record per pagina = 4096/48 = 85
• P(P) = 50K/85 = 589
• Dimensione di Progetti:
• Numero di record per pagina = 4096/64 = 64
• P(P) = 4K/64 = 63
• Indice Personale.cod:
• Dimensione entry = 10 + 4 = 14B
• Numero di entry per foglia = 4096 x 0.7/14 = 204
• Numero di foglie = NK(cod)/204
= 50K/204 = 245
86
Soluzione (ii)
• Indice Personale.mansione:
• Dimensione entry = 20 + 50K/1K x 4 = 220B
• Numero di entry per foglia = 4096 x 0.7/220 = 13
• Numero di foglie = NK(mansione)/13 = 1K/13 = 77
• Indice Personale.proj:
• Dimensione entry = 10 + 50K/4K x 4 = 60B
• Numero di entry per foglia = 4096 x 0.7/60 = 48
• Numero di foglie = NK(proj)/48 = 4K/48 = 84
87
Soluzione (iii)
• Indice Progetti.cod:
• Dimensione entry = 10 + 4 = 14B
• Numero di entry per foglia = 4096 x 0.7/14 = 204
• Numero di foglie = NK(cod)/204 = 4K/204 = 20
• Indice Progetti.consegna:
• Dimensione entry = 8 + 4K/365 x 4 = 52B
• Numero di entry per foglia = 4096 x 0.7/52 = 55
• Numero di foglie = NK(proj)/55 = 365/55 = 7
88
Soluzione (iv)
• Fattore di selettività dei predicati:
• Personale.mansione = 1/NK(mansione) = 1/1000
• Progetto.consegna = 31/365
• Progetto.sede = 1/NK(sede) = 1/100
• Cardinalità del risultato:
• Progetti che soddisfano i predicati =
4K/100 x 31/365 = 4
• Personale che soddisfa il predicato = 50K/1K = 50
• Personale nel risultato = 50 x 4/4000 = 1
89
Soluzione (v)
• Valutiamo il piano Personale  Progetti
• Accesso a Personale (esterna):
• Senza indice:
• Costo = P(P) = 589
• Indice su mansione (clust.):
• Costo = f x L(mansione) + f x P(P) = 77/1000 + 589/1000
=1+1=2
• La dimensione del risultato è
f x N(P) = 50K/1000 = 50
90
Soluzione (vi)
• Accesso a Progetti (interna):
• Senza indice:
• Costo = P(PR) = 63
• Indice su cod (uncl.):
• Costo = 1 + 1 = 2 (cod chiave di PR)
• Indice su consegna (clust.):
• Costo = f x L(consegna) + f x P(PR)
= 7 x 31/365 + 63 x 31/365 = 1 + 6 = 7
• Costo totale = 2 + 50 x 2 = 102
91
Soluzione (vii)
• Valutiamo il piano Progetti  Personale
• Accesso a Progetti (esterna):
• Senza indice:
• Costo = P(PR) = 63
• Indice su consegna (clust.):
• Costo = f x L(consegna) + f x P(PR)
= 7 x 31/365 + 63 x 31/365 = 1 + 6 = 7
• La dimensione del risultato è
f x N(P) = 4K/100 x 31/365 = 4
92
Soluzione (viii)
• Accesso a Personale (interna):
• Senza indice:
• Costo = P(P) = 589
• Indice su proj (uncl.):
• Costo = f x L(proj) + Φ(f x N(P),P(P))
= 84/4000 + Φ(50K/4K,589) = 1 + 13 = 14
• Indice su mansione (clust.):
• Costo = f x L(mansione) + f x P(P) = 77/1000 + 589/1000
=1+1=2
• Costo totale = 7 + 4 x 2 = 15
93