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=100val>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=100val>4(Recensionisid=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=100val>4 svid=100val>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=100val>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 2N 1! N! 2N 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