Ottimizzazione Ottimizzazione Nel modello relazionale la locazione fisica dei dati non è importante. Anche in un DBMS la locazione fisica dei dati dell utente e l operazione utilizzata per recuperarli non sono importanti. Quanto meglio si comprende il percorso esecutivo utilizzato per eseguire la query, tanto meglio si riuscirà a gestire e regolare la query stessa. Ottimizzazione 2
Quale Ottimizzatore Oracle ottimizzatore basato sulle regole (RBO). Esso valuta i percorsi esecutivi possibili e fa una stima dei percorsi esecutivi alternativi in base a una serie di regole di sintassi. Ottimizzatore basato sui costi (CBO). Si può utilizzare il comando analyze per generare statistiche relative agli oggetti del proprio database. Le statistiche includono il numero di righe in una tabella e il numero di chiavi distinte presenti all interno di un indice. In base a queste informazioni statistiche, l ottimizzatore basato sui costi valuta il costo dei percorsi esecutivi disponibili e seleziona il percorso che ha il costo relativo più basso Ottimizzazione 3 Operazioni di Accesso alle Tabelle Accesso Completo Durante una scansione completa di una tabella vengono lette in sequenza tutte le righe della tabella. L ottimizzatore chiama questo tipo di operazione TABLE ACCESS FULL select * from LAVORATORE; nel momento in cui la tabella LAVORATORE aumenta di dimensione, aumentano anche i costi dell operazione in termini di prestazioni. Se più utenti eseguono scansioni complete della tabella, i costi associati crescono ancora più velocemente. Ottimizzazione 4
Operazioni di Accesso alle Tabelle Accesso per RowID Per migliorare le prestazioni delle operazioni di accesso alle tabelle si possono utilizzare le operazioni che consentono di impiegare i valori della pseudocolonna RowID per accedere alle righe della tabella. RowID registra la locazione fisica in cui è memorizzata la riga. Si utilizzano gli indici per mettere in relazione i valori dei dati con i valori di RowID e così con le locazioni fisiche dei dati. Ottimizzazione 5 Operazioni che utilizzano Indici create table ALLOGGIO ( Alloggio VARCHAR2(15) not null, NomeLungo VARCHAR2(40), Direttore VARCHAR2(25), Indirizzo VARCHAR2(30) ); alter table ALLOGGIO add constraint ALLOGGIO_PK primary key (Alloggio) create index ALLOGGIO$DIRETTORE on ALLOGGIO(Direttore) Ottimizzazione 6
Index Unique Scan Operazioni che utilizzano Indici select * where Alloggio = Milano ; Index Range Scan select * where Alloggio like M% ; select Alloggio where Direttore = Valentino ; Ottimizzazione 7 Index Range Scan Operazioni che utilizzano Indici select * where Alloggio like M% ; select Alloggio where Direttore = Antonio ; (l indice sul direttore non è unico) Ottimizzazione 8
Cosa succede se? select * Operazioni che utilizzano Indici where Alloggio like %M% ; select Alloggio where upper(direttore) = ANTONIO ; select Alloggio where Direttore is NULL; select Alloggio where Direttore is NOT NULL; Ottimizzazione 9 Operazioni che utilizzano Indici select Alloggio where Direttore is NOT NULL; select Nome from LAVORATORE where Alloggio not in (select Alloggio where Direttore = Antonio ); select Nome from LAVORATORE where Alloggio in (select Alloggio Direttore = Antonio ); continuare da qui where Direttore = Antonio ); Ottimizzazione 10
Operazioni che utilizzano Indici select Min(direttore) select * where Alloggio > M and Direttore > M ; In generale, gli accessi a un unico indice a più colonne (in cui la colonna principale viene utilizzata in una condizione di limitazione ione all interno della clausola where della query) rispondono meglio rispetto a un operazione AND-EQUAL di più indici a una sola colonna. Ottimizzazione 11 Selettività degli Indici Se si sta utilizzando il CBO, l ottimizzatore può sfruttare la selettività dell indice per giudicare se l indice sia in grado di abbassare il costo dell esecuzione della query. Se l indice è altamente selettivo, allora viene associato un numero basso di record a ciascun valore distinto della colonna. Esempio: se vi sono 100 record in una tabella e 80 valori distinti per una colonna di quella tabella, la selettività di un indice su quella colonna è di 80/100 = 0.80. Maggiore è la selettività, minore è il numero di righe restituite e per ciascun valore distinto nella colonna. Il numero di righe restituite per valore distinto è importante nella fase di scansione di un intervallo di valori. Se un indice ha una bassa selettività, le molte operazioni di INDEX RANGE SCAN e di TABLE ACCESS BY ROWID utilizzate per recuperare i dati possono richiedere un lavoro maggiore rispetto all operazione di TABLE ACCESS FULL di una tabella. Ottimizzazione 12
select * Concatenazioni where Direttore in ( Antonio, Giuseppe ); select * where Direttore = Antonio or Direttore = Giuseppe ; Ottimizzazione 13 Indici Concatenati In generale l ottimizzatore riesce a scandire più velocemente un unico indice concatenato che non a leggere e unire due indici separati. Se si aggiungono ulteriori colonne all indice concatenato, risulta meno efficiente per scansioni di intervalli. Per l indice concatenato, quale colonna dovrebbe essere la principale? Questa colonna dovrebbe essere utilizzata di frequente come condizione di limitazione per la tabella e dovrebbe essere altamente selettiva. l ottimizzatore basa le proprie valutazioni relative alla selettività dell indice sulla selettività della colonna principale. Se la colonna principale di un indice non è presente in una condizione di limitazione l indice non viene chiamato in causa. Ottimizzazione 14
Operazioni che gestiscono insiemi di dati Dopo che i dati sono stati restituiti dalla tabella o dall indice, è possibile operare su di essi. Si possono raggruppare i record, ordinarli, contarli, bloccarli o unire i risultati di una query con quelli di altre (tramite gli operatori UNION, MINUS e INTERSECT). La maggior parte delle operazioni che agiscono su gruppi di record non restituisce i record agli utenti fino a che l intera operazione non viene completata select Nome, Eta from LAVORATORE order by Eta; Ottimizzazione 15 Operazioni che gestiscono insiemi di dati select DISTINCT Eta from LAVORATORE; TABLE ACCESS FULL + SORT UNIQUE select Alloggio, COUNT(*) from LAVORATORE group by Alloggio; TABLE ACCESS FULL + SORT GROUP BY Ottimizzazione 16
Operazioni che gestiscono insiemi di dati Quando si mette a punto una query per un utente in linea è consigliabile evitare di utilizzare le operazioni di ordinamento e di raggruppamento che costringano gli utenti ad aspettare che i record vengano elaborati. Quanto meno operazioni di ordinamento e di raggruppamento vengono eseguite, tanto più velocemente viene restituito all utente il primo record trovato. In una transazione batch le prestazioni della query vengono misurate in base al tempo complessivo impiegato per il completamento della query, non al tempo necessario per restituire la prima riga. Ottimizzazione 17 Operazioni che gestiscono insiemi di dati select Nome from PROSPETTIVA UNION select Nome from DIPENDENTE; select Nome from PROSPETTIVA UNION ALL select Nome from DIPENDENTE; MINUS, INTERSECT Ottimizzazione 18
Operazioni che gestiscono insiemi di dati Ogni volta che è possibile, l ottimizzatore combina il testo proveniente da una sottoquery con il resto della query. select * from LAVORATORE where Alloggio = (select Alloggio where Direttore = 'Antonio') select LAVORATORE.* from LAVORATORE, ALLOGGIO where LAVORATORE.Alloggio = ALLOGGIO.Alloggio and Direttore = 'Antonio'; Ottimizzazione 19 Operazioni che gestiscono insiemi di dati select Nome from LAVORATORE where Eta > (select AVG(Eta) from LAVORATORE); l ottimizzatore non può unire la sottoquerye e il testo della query che la richiama. Di conseguenza, la sottoqueryviene elaborata per prima; Ottimizzazione 20
Operazioni che gestiscono insiemi di dati è è opportuno cercare di ridurre il numero di operazioni di ordinamento. quando si eseguono operazioni che manipolano gruppi di record, è consigliabile ridurre il numero di operazioni di ordinamento annidate. Ad esempio, l UNION di query in cui ciascuna query contiene una clausola group by, richiede degli ordinamenti annidati; viene richiesta un operaz ione di ordinamento per ciascuna delle query, seguita da un operazione di SORT UNIQUE richiesta per la UNION. L operazione di ordinamento richiesta per la UNION non può iniziare fino a che gli ordinamenti per le clausole group by non sono stati ompletati. Tanto più profondamente sono annidati gli ordinamenti, tanto maggiore giore risulta l impatto delle querysulle prestazioni. Se si stanno utilizzando funzioni UNION, è opportuno controllare le strutture e i dati delle tabelle per verificare se è possibile che entrambe le queryrestituiscano restituiscano gli stessi record. Ad esempio, è possibile interrogare i dati da due sorgenti separ ate e riportare i risultati attraverso un unica query utilizzando la funzione UNION. Se non è possibile che le due queryrestituiscano restituiscano le stesse righe, si può rimpiazzare la funzione UNION con UNION ALL ed evitare così l operazione SORT UNIQUE eseguita dalla funzione UNION. Ottimizzazione 21 Operazioni di Join Se in una query vengono unite più di due tabelle fra loro, l ottimizzatore tratta la query come un insieme di più unioni. Ad esempio, se la query esegue l unione di tre tabelle, l ottimizzatore unisce prima due tabelle assieme e successivamente i risultati ottenuti con la terza tabella. La dimensione dei risultati dell unione iniziale influisce sulle prestazioni delle restanti unioni. Ottimizzazione 22
Operazioni di Join select LAVORATORE.Nome, ALLOGGIO.Direttore from LAVORATORE, ALLOGGIO where LAVORATORE.Alloggio = ALLOGGIO.Alloggio; (LAVORATORE.Alloggio = ALLOGGIO.NomeLungo) Le operazioni di MERGE JOIN vengono comunemente utilizzate quando non vi sono indici disponibili per le condizioni di limitazione della query. Che cosa accade se la tabella ALLOGGIO possiede 100 voci e la tabella LAVORATORE 10000? Le operazioni di TABLE ACCESS FULL e SORT JOIN per la tabella ALLOGGIO LOGGIO vengono completate velocemente. Tuttavia, l operazione di MERGE JOIN non può iniziare fino a che non sono state completate le operazioni di TABLE ACCESS FULL e SORT JOIN della tabella LAVORATORE, che richiedono più tempo. Ottimizzazione 23 Operazioni di Join NESTED LOOPS select LAVORATORE.Nome, ALLOGGIO.Direttore from LAVORATORE, ALLOGGIO where LAVORATORE.Alloggio = ALLOGGIO.Alloggio; Per effettuare un unione NESTED LOOPS, l ottimizzatore deve innanzitutto nzitutto selezionare la tabella guida, ovvero la tabella che viene letta per prima Poiché sulla colonna Alloggio della tabella omonima è disponibile un indice e nessun indice simile è invece disponibile per la tabella LAVORATORE, ORE,quest quest ultima ultima viene utilizzata come tabella guida della query. Se la tabella guida è grande, l operazione di TABLE ACCESS FULL eseguita su di essa può influire negativamente sulle prestazioni della query. Ottimizzazione 24
Operazioni di Join MERGE JOIN si basa su operazioni di insieme, non restituisce alcun record all utente fino a che tutte le righe non sono state elaborate. NESTED LOOPS è in grado di restituire le righe all utente appena risultano disponibili.. Ottimizzazione 25 1. Complete SQL text from V$SQLTEXT 2. Structure of the tables referenced in the SQL statement 3. Definitions of any indexes (columns, column orderings), and w hether the indexes are unique or nonunique 4. CBO statistics for the segments (including the number of rowseach table, selectivity of the index columns), including the date when the segments were last analyzed 5. Definitions of any views referred to in the SQL statement 6. Repeat steps two and three for any tables referenced in the view definitions found in step four 7. Optimizer plan for the SQL statement (either from EXPLAIN PLAN, V$SQL_ PLAN, or the TKPROF output) 8. Any previous optimizer plans for that SQL statement Ottimizzazione 26
Verifying Optimizer Statistics Reviewing the Execution Plan Restructuring the SQL Statements Restructuring the Indexes Modifying or Disabling Triggers and Constraints Restructuring the Data Maintaining Execution Plans Over Time Visiting Data as Few Times as Possible Ottimizzazione 27 Verifying Optimizer Statistics The CBO uses statistics gathered on tables and indexes when determining the optimal execution plan. If these statistics have not been gathered, ed, or if the statistics are no longer representative of the data stored within the database, ase, then the optimizer does not have sufficient information to generate the best plan. Things to check: n n If you gather statistics for some tables in your database, then it is probably best to gather statistics for all tables. This is especially true if your application includes SQL statements that perform joins. n n If the optimizer statistics in the data dictionary are no longer representative of the data in the tables and indexes, then gather new statistics. One way to check whether the dictionary statistics are stale is to compare the real cardinality (row count) of a table to the value of DBA_TABLES.NUM_ROWS. If there is significant data skew on predicate columns, then consider using histograms. Ottimizzazione 28
Execution Plan When tuning (or writing) a SQL statement in an OLTP environment, the goal is to drive from the table that has the most selective filter. This means that there are fewer rows passed to the next step. If the next step is a join, then this means that fewer rows are joined. Check to see whether the access paths are optimal. When examining the optimizer execution plan, look for the following: n n The plan is such that the driving table has the best filter. n n The join order in each step means that the fewest number of rows are being returned to the next step (that is, the join order should reflect, where possible, going to the best not-yet-used filters). n n The join method is appropriate for the number of rows being returned. For example, nested loop joins through indexes may not be optimal when many rows are being returned. n n Views are used efficiently. Look at the SELECT list to see whether access to the view is necessary. n n There are any unintentional Cartesian products (even with small l tables). n n Each table is being accessed efficiently: Consider the predicates in the SQL statement and the number of rows in the table. Look for suspicious activity, such as a full table scans on tables with large number Ottimizzazione 29 of rows, which have predicates in the where clause. Determine why an index is not used for such a selective predicate. Componi predicati usando AND e = Evitare colonne trasformate nella clausola WHERE WHERE a.order_no = b.order_no Piuttosto che WHERE TO_NUMBER (SUBSTR(a.order_no, INSTR(b.order_no,. ) - 1)) = TO_NUMBER (SUBSTR(a.order_no, INSTR(b.order_no,. ) - 1)) Ottimizzazione 30
E meglio scrivere istruzioni SQL separate. Se bisogna avere query complesse utilizzare se possibilie UNION ALL SELECT info FROM tables WHERE... AND somecolumn BETWEEN DECODE(:loval, 'ALL', somecolumn, :loval) AND DECODE(:hival, 'ALL', somecolumn, :hival); SELECT /* change this half of UNION ALL if other half changes */ info FROM tables WHERE... AND somecolumn BETWEEN :loval AND :hival AND (:hival!= 'ALL' AND :loval!= 'ALL') UNION ALL SELECT /* Change this half of UNION ALL if other half changes. */ info FROM tables WHERE... AND (:hival = 'ALL' OR :loval = 'ALL'); Ottimizzazione 31 EXISTS vs IN In generale se il predicato selettivo è nella subqueryusareusare IN Se è nella query genitore, usare EXISTS SELECT /* EXISTS example */ e.employee_id, e.first_name, e.last_name, e.salary FROM employees e WHERE EXISTS (SELECT 1 FROM orders o WHERE e.employee_id = o.sales_rep_id AND o.customer_id = 144); Ottimizzazione 32
EXISTS vs IN SELECT /* IN example */ e.employee_id, e.first_name, e.last_name, e.salary FROM employees e WHERE e.employee_id IN (SELECT o.sales_rep_id FROM orders o WHERE o.customer_id = 144); Ottimizzazione 33 EXISTS vs IN SELECT /* IN example */ e.employee_id, e.first_name, e.last_name, e.department_id, e.salary FROM employees e WHERE e.department_id = 80 AND e.job_id = 'SA_REP AND e.employee_id IN (SELECT o.sales_rep_idfrom orders o); Ottimizzazione 34
EXISTS vs IN SELECT /* EXISTS example */ e.employee_id, e.first_name, e.last_name, e.salary FROM employees e WHERE e.department_id = 80 AND e.job_id = 'SA_REP' AND EXISTS (SELECT 1 FROM orders o WHERE e.employee_id = o.sales_rep_id); Ottimizzazione 35 EXISTS SELECT SUM(A.col2) FROM MytableA A WHERE ( SELECT COUNT(*) FROM MytableBB WHERE B.Col1 = A.Col1) > 0 Provare con SELECT SUM(A.col2) FROM MytableA A WHERE EXISTS( SELECT * FROM MytableBB WHERE B.Col1 = A.Col1) Ottimizzazione 36
Viste Cautela quando si usano Join su Viste complesse Spesso il risultato dell intera vista è instanziato e dopo la query è eseguita sui dati della vista Prima di usara una vista, determinare se tutte le tabelle nella vista sono necessarie per i dati richiesti Ottimizzazione 37 Memorizzare risultati intermedi -Si potrebbero migliorare le prestazioni, specialmente nel caso di riuso - Query lunghe e complesse possono essere di difficile comprensione -Considerare l uso di viste materializzate Ottimizzazione 38
Ristrutturare gli indici -Rimuovere indici non selettiviper velocizzare le DML -Riordinare le colonne negli indici esistenti -Aggiungere colonne per migliorare la selettività -Non considerare l aggiunta di indici come una panacea -se un singolo programmatore crea un indice appropriato, allora si può migliorare la performance; -Se 50 programmatori creano ognuno un indice, allora la performance probabilmente degrada Ottimizzazione 39 Modificare o disabilitare Triggers e Vincoli Ottimizzazione 40
Ristrutturazione dei dati Introdurre valori derivati. Evitare GROUP BY in codice response-critical Rivedere il disegno del database Considerare il partitioning, se appropriato Ottimizzazione 41 Ridurre il traffico di rete e il database load SELECT COUNT (*) FROM employees WHERE salary < 2000; SELECT COUNT (*) FROM employees WHERE salary BETWEEN 2000 AND 4000; SELECT COUNT (*) FROM employees WHERE salary>4000; Ottimizzazione 42
Ridurre il traffico di rete e il database load Trasformarle in SELECT COUNT (CASE WHEN salary < 2000 THEN 1 ELSE null END) count1, COUNT (CASE WHEN salary BETWEEN 2001 AND 4000 THEN 1 ELSE null END) count2, COUNT (CASE WHEN salary > 4000 THEN 1 ELSE null END) count3 FROM employees; Ottimizzazione 43 Ridurre il traffico di rete e il database load Evitare il SELECT * Se l applicazione usa il looping, provare ad inserirlo nella query: spesso un applicazione contiene un loop che include una query parametrizzata che viene eseguita molte volte e richiede un round-triptratra l applicazione e il DB server. Creare ad esempio tabelle temporanee Ottimizzazione 44
Utilizzare Stored Procedure Velocità Riduzione traffico di rete Potenza Non portabilità Conoscenzadel linguaggio procedurale Ottimizzazione 45