Sei sulla pagina 1di 44

SQL PERFORMANCE & TUNING

8. Sql Tips & Tricks

Atos, Atos and fish symbol, Atos Origin and fish symbol, Atos Consulting, and the fish symbol itself are registered trademarks of Atos Origin SA. 30 December 2021
© 2006 Atos Origin. Private for the client. This report or any part of it, may not be copied, circulated, quoted without prior written approval from Atos Origin or the
client.
Obiettivi

In questo paragrafo verranno affrontati i seguenti argomenti:


 Utilizzo corretto degli indici
 I diversi costrutti SQL, le alternative

2 Custom presentation- or document control name


Gli Indici e la Selettività

 La convenienza nell’utilizzo di un indice dipende


strettamente dalla selettività dell’indice stesso.
 A volte, specialmente per tabelle piccole, può essere più
conveniente un full-table-scan.
 In genere, l’utilizzo di un indice risulta conveniente se la
sua selettività è inferiore al 5%.

3 Custom presentation- or document control name


Full-Table-Scan contro Index-Scan

 Dimensione di un blocco del sistema operativo


 Tipologia del file-system (utilizzo o meno di raw device)
 Utilizzo o meno di striping e/o mirroring dei dati (RAID)
 Dimensione di un blocco dell’istanza (DB_BLOCK_SIZE)
 Dimensionamento della SGA
 Grado di Parallelismo della query
 Il parametro DB_FILE_MULTIBLOCK_READ_COUNT

4 Custom presentation- or document control name


La conversione implicita dei tipi

 L’utilizzo di operandi di tipo diverso in una espressione è


fortemente sconsigliato.
 Devono essere sempre utilizzate le opportune funzioni di
conversione (TO_CHAR(), TO_DATE(), …) e non si deve
mai fare affidamento sulla conversione implicita dei tipi.
 Oracle converte implicitamente tutti i tipi a NUMBER.
 Oracle restituisce un errore se una colonna CHAR viene
confrontata con una espressione numerica e la colonna
contiene dei caratteri non numerici.

5 Custom presentation- or document control name


La scelta tra FIRST_ROWS e ALL_ROWS

E’ importante stabilire lo scopo dello statement.

 Utilizzare l’hint FIRST_ROWS se si vuole minimizzare il


tempo di risposta o se si vuole ottenere il risultato di una
query “n righe alla volta”.
 Utilizzare l’hint ALL_ROWS se è più importante
ottimizzare il tempo totale di esecuzione rispetto al tempo di
risposta.

6 Custom presentation- or document control name


I Trigger

 L’utilizzo dei trigger è, in genere, sconsigliato.


 I trigger, se non gestiti con attenta cautela, possono
provocare dei seri problemi prestazionali (dml su grandi
quantità di dati e “cascading-triggers”).
 In generale, all’interno di un trigger ci deve essere soltanto
una chiamata a stored-procedure (versioni di oracle
precedenti alla 8.x ricompilano il trigger ogni volta che viene
richiamato).

7 Custom presentation- or document control name


Gli Indici e la distribuzione dei dati

 Il CBO assume che la distribuzione dei dati di un indice sia


uniforme (a meno che non si utilizzino gli istogrammi).
 Se un indice ha una distribuzione non uniforme dei dati, il
CBO può scegliere un piano di esecuzione non ottimale.
 Se vengono utilizzate delle bind-variable il CBO non
conoscendo a priori il suo valore effettua delle “assunzioni”
sulla selettività degli indici. Questo può portare a piani di
esecuzione non ottimali.
 In tal caso è bene utilizzare degli HINT per pilotare il CBO
nella scelta corretta.

8 Custom presentation- or document control name


Esempio (1) - gli Indici e la distribuzione dei
dati

SELECT empno, ename


FROM emp
WHERE sex='F';

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=6 Bytes=54)
1 0 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=6 Bytes=54)

9 Custom presentation- or document control name


Esempio (2) - gli Indici e la distribuzione dei
dati

SELECT /*+ INDEX_ASC (emp emp_ix1) */ empno, ename


FROM emp
WHERE sex='F’;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=6 Bytes=54)
1 0 TABLE ACCESS (BY IX ROWID) OF 'EMP' (Cost=2 Card=6 Bytes=54)
2 1 INDEX (RANGE SCAN) OF 'EMP_IX1' (NON-UNIQUE) (Cost=1 Card=6)

10 Custom presentation- or document control name


Gli Indici e le Funzioni

 L’utilizzo di funzioni sulle colonne di un indice disabilita


l’uso dell’indice stesso.
 Per funzione si intende sia una funzione SQL (ROUND(),
UPPER(), ecc …) sia una espressione in cui uno degli operandi
è la colonna indicizzata (a+2, a || ‘stringa’, ecc …).

11 Custom presentation- or document control name


Esempio (1) - gli Indici e le Funzioni

SELECT *
FROM emp
WHERE empno/10 = 790;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=33)
1 0 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=1 Bytes=33)

12 Custom presentation- or document control name


Esempio (2) - gli Indici e le Funzioni

SELECT *
FROM emp
WHERE empno = 790*10;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=33)
1 0 TABLE ACCESS (BY IX ROWID) OF 'EMP' (Cost=1 Card=1 Bytes=33)
2 1 INDEX (UNIQUE SCAN) OF 'PK_EMP' (UNIQUE)

13 Custom presentation- or document control name


Gli Indici ed i valori NULL

 I valori NULL non sono memorizzati all’interno di un


indice (b-tree).
 Una selezione su una colonna indicizzata del tipo IS NULL
non utilizza l’indice.

14 Custom presentation- or document control name


Esempio - gli Indici ed i valori NULL

SELECT /*+ INDEX_ASC(dept dept_ix1) */ deptno, dname


FROM dept
WHERE dname IS NULL;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=11)
1 0 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=1 Bytes=11)

15 Custom presentation- or document control name


Gli Indici e gli operatori != (diverso) e NOT

I seguenti operatori disabilitano l’utilizzo degli indici definiti


sulle colonne su cui viene fatta la selezione:
 L’operatore != (diverso)
 L’operatore NOT

Eccezioni al caso (2) si hanno nei seguenti casi:


(2.a) NOT > trasformato in <=
(2.b) NOT >= trasformato in <
(2.c) NOT < trasformato in >=
(2.d) NOT <= trasformato in >

16 Custom presentation- or document control name


Esempio - gli Indici e gli operatori != (diverso)
e NOT

SELECT /*+ INDEX_ASC(dept dept_ix1) */ deptno, dname


FROM dept
WHERE dname != 'SALES’;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=3 Bytes=33)
1 0 TABLE ACCESS (BY IX ROWID) OF 'DEPT' (Cost=2 Card=3 Bytes=33)
2 1 INDEX (FULL SCAN) OF 'DEPT_IX1' (NON-UNIQUE) (Cost=1 Card=3)

17 Custom presentation- or document control name


La clausola DISTINCT

 L’utilizzo della clausola DISTINCT obbliga oracle a


recuperare tutte le righe associate ad uno statement e
successivamente a fare un sort.
 La clausola DISTINCT deve essere utilizzata soltanto nei
casi di effettiva necessità.

18 Custom presentation- or document control name


Esempio - la clausola DISTINCT

SELECT DISTINCT deptno, dname


FROM dept;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=4 Bytes=44)
1 0 SORT (UNIQUE) (Cost=3 Card=4 Bytes=44)
2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=4 Bytes=44)

19 Custom presentation- or document control name


Utilizzo di IN o di EXISTS

 E’ preferibile utilizzare l’operatore IN quando esiste un


indice sulle colonne della outer-table e la inner-table è
“piccola” rispetto alla outer-table.
 E’ preferibile utilizzare l’operatore EXISTS quando esiste
un indice sulle colonne delle inner-table e la inner_table è
“grande” rispetto alla outer-table.

20 Custom presentation- or document control name


Esempio (1) - utilizzo di IN o di EXISTS

SELECT *
FROM dept
WHERE deptno IN (SELECT deptno FROM emp);

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=3 Bytes=93)
1 0 NESTED LOOPS (Cost=6 Card=3 Bytes=93)
2 1 VIEW OF 'VW_NSO_1' (Cost=3 Card=3 Bytes=39)
3 2 SORT (UNIQUE) (Cost=3 Card=3 Bytes=6)
4 3 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=12 Bytes=24)
5 1 TABLE ACCESS (BY IX ROWID) OF 'DEPT' (Cost=1 Card=4 Bytes=72)
6 5 INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)

21 Custom presentation- or document control name


Esempio (2) - utilizzo di IN o di EXISTS

SELECT *
FROM dept a
WHERE EXISTS (SELECT 1 FROM emp b WHERE b.deptno=a.deptno);

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=18)
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=1 Bytes=18)
3 1 INDEX (RANGE SCAN) OF 'EMP_IX2' (NON-UNIQUE) (Cost=1 Card=4
Bytes=8)

22 Custom presentation- or document control name


Utilizzo di NOT IN o di NOT EXISTS

 L’operatore NOT IN causa un sort delle righe della inner-


table. Perciò, è preferibile utilizzare l’operatore NOT
EXISTS nei casi in cui la inner-table ha dimensioni
considerevoli ed esiste un indice sulle colonne della inner-
table.

(*) Attenzione gli operatori NOT IN e NOT EXISTS non


sono equivalenti (attenzione ad i valori NULL ritornati dalla
subquery).

23 Custom presentation- or document control name


Esempio (1) - utilizzo di NOT IN o di NOT
EXISTS

SELECT *
FROM dept
WHERE deptno NOT IN (SELECT deptno FROM emp);

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=18)
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=1 Bytes=18)
3 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=1 Bytes=2)

24 Custom presentation- or document control name


Esempio (2) - utilizzo di NOT IN o di NOT
EXISTS

SELECT *
FROM dept a
WHERE NOT EXISTS (SELECT 1 FROM emp b WHERE b.deptno = a.deptno);

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=18)
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=1 Bytes=18)
3 1 INDEX (RANGE SCAN) OF 'EMP_IX2' (NON-UNIQUE) (Cost=1 Card=4
Bytes=8)

25 Custom presentation- or document control name


Utilizzo di WHERE o di HAVING

 La clausola HAVING filtra il risultato dopo che tutte le


righe sono state elaborate. Utilizzare quando è possibile la
clausola WHERE.

26 Custom presentation- or document control name


Esempio (1) - utilizzo di WHERE o di HAVING

SELECT deptno, COUNT(*)


FROM emp
GROUP BY deptno
HAVING deptno = 30;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=2)
1 0 FILTER
2 1 SORT (GROUP BY) (Cost=3 Card=1 Bytes=2)
3 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=12 Bytes=24)

27 Custom presentation- or document control name


Esempio (2) - utilizzo di WHERE o di HAVING

SELECT deptno, COUNT(*)


FROM emp
WHERE deptno = 30
GROUP BY deptno;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=2)
1 0 SORT (GROUP BY NOSORT) (Cost=1 Card=1 Bytes=2)
2 1 INDEX (RANGE SCAN) OF 'EMP_IX2' (NON-UNIQUE) (Cost=1 Card=4
Bytes=8)

28 Custom presentation- or document control name


Utilizzo di EXISTS o di DISTINCT

 Se si vogliono selezionare le righe distinte di una entità in


relazione 1:n con un’altra è bene evitare di utilizzare la
clausola DISTINCT con l’operatore di join. Infatti in questo
modo viene da prima fatto il join delle 2 tabelle e
successivamente il sort ed il filter per eliminare le righe
duplicate.
 Deve esistere un indice sulle colonne della subquery.
 In questo caso è più efficiente utilizzare una sub-query con
una EXISTS.

29 Custom presentation- or document control name


Esempio (1) - utilizzo di EXISTS o di DISTINCT

SELECT DISTINCT a.deptno, a.dname


FROM dept a, emp b
WHERE b.deptno = a.deptno;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=9 Bytes=117)
1 0 SORT (UNIQUE) (Cost=3 Card=9 Bytes=117)
2 1 NESTED LOOPS (Cost=1 Card=12 Bytes=156)
3 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=4 Bytes=44)
4 2 INDEX (RANGE SCAN) OF 'EMP_IX2' (NON-UNIQUE)

30 Custom presentation- or document control name


Esempio (2) - utilizzo di EXISTS o di DISTINCT

SELECT a.deptno, a.dname


FROM dept a
WHERE EXISTS (SELECT 1 FROM emp b WHERE b.deptno = a.deptno);

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=11)
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=1 Bytes=11)
3 1 INDEX (RANGE SCAN) OF 'EMP_IX2' (NON-UNIQUE) (Cost=1 Card=4
Bytes=8)

31 Custom presentation- or document control name


Utilizzo di UNION o UNION ALL

 La clausola UNION implica un sort delle tabelle coinvolte


ed un successivo merge. Questo avviene per poter eliminare
le righe duplicate. Se si è sicuri che non vi siano righe
duplicate utilizzare la clausola UNION ALL.

32 Custom presentation- or document control name


Esempio (1) - utilizzo di UNION o UNION ALL

SELECT empno, ename, deptno


FROM emp
WHERE deptno = 10
UNION
SELECT empno, ename, deptno
FROM emp
WHERE deptno = 20;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=8 Bytes=80)
1 0 SORT (UNIQUE) (Cost=6 Card=8 Bytes=80)
2 1 UNION-ALL
3 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=4 Bytes=40)
4 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=4 Bytes=40)

33 Custom presentation- or document control name


Esempio (2) - utilizzo di UNION o UNION ALL

SELECT empno, ename, deptno


FROM emp
WHERE deptno = 10
UNION ALL
SELECT empno, ename, deptno
FROM emp
WHERE deptno = 20;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=8 Bytes=80)
1 0 UNION-ALL
2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=4 Bytes=40)
3 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=4 Bytes=40)

34 Custom presentation- or document control name


Utilizzo di UNION al posto di OR

 L’utilizzo dell’operatore OR, in genere, implica una full-


table-scan della tabella.
 E’ conveniente utilizzare la UNION al posto dell’OR
quando le colonne su cui si effettua la selezione sono
indicizzate.
 E’ conveniente utilizzare la UNION al posto dell’OR
quando la query restituisce poche righe.

35 Custom presentation- or document control name


Esempio (1) - utilizzo di UNION al posto di OR

SELECT *
FROM dept
WHERE deptno=20 OR dname='SALES’;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=2 Bytes=36)
1 0 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=2 Bytes=36)

36 Custom presentation- or document control name


Esempio (2) - utilizzo di UNION al posto di OR

SELECT /*+ INDEX_ASC(dept pk_dept) */ * FROM dept WHERE deptno=20


UNION
SELECT /*+ INDEX_ASC(dept dept_ix1) */ * FROM dept WHERE dname='SALES’;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=7 Card=2 Bytes=36)
1 0 SORT (UNIQUE) (Cost=7 Card=2 Bytes=36)
2 1 UNION-ALL
3 2 TABLE ACCESS (BY IX ROWID) OF 'DEPT' (Cost=1 Card=1 Bytes=18)
4 3 IX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)
5 2 TABLE ACCESS (BY IX ROWID) OF 'DEPT' (Cost=2 Card=1 Bytes=18)
6 5 IX (RANGE SCAN) OF 'DEPT_IX1' (NON-UNIQUE) (Cost= 1 Card=1)

37 Custom presentation- or document control name


Update di più colonne

 Per effettuare l’update di più colonne di una stessa tabella (a


partire da una tabella data) è conveniente minimizzare il numero
di subquery.

UPDATE <table1>
SET (<field1>, <field2>) = (
SELECT <field1>, <field2>
FROM <table2>
WHERE ...)
WHERE … ;

38 Custom presentation- or document control name


Esempio (1) - update di più colonne

UPDATE bonus a
SET a.sal = (SELECT b.sal FROM emp b WHERE b.deptno = 10),
a.comm = (SELECT b.comm FROM emp b WHERE b.deptno = 10);

Execution Plan
----------------------------------------------------------
0 UPDATE STATEMENT Optimizer=CHOOSE (Cost=1 Card=21 Bytes=546)
1 0 UPDATE OF 'BONUS'
2 1 TABLE ACCESS (FULL) OF 'BONUS' (Cost=1 Card=21 Bytes=546)
3 0 TABLE ACCESS (BY IX ROWID) OF 'EMP' (Cost=2 Card=4 Bytes=20)
4 3 INDEX (RANGE SCAN) OF 'EMP_IX2' (NON-UNIQUE) (Cost=1 Card=4)
5 0 TABLE ACCESS (BY IX ROWID) OF 'EMP' (Cost=2 Card=4 Bytes=16)
6 5 INDEX (RANGE SCAN) OF 'EMP_IX2' (NON-UNIQUE) (Cost=1 Card=4)

39 Custom presentation- or document control name


Esempio (2) - update di più colonne

UPDATEbonus a
SET (a.sal, a.comm) = (SELECT b.sal, b.comm FROM emp b
WHERE b.deptno = 10);

Execution Plan
----------------------------------------------------------
0 UPDATE STATEMENT Optimizer=CHOOSE (Cost=1 Card=21 Bytes=546)
1 0 UPDATE OF 'BONUS'
2 1 TABLE ACCESS (FULL) OF 'BONUS' (Cost=1 Card=21 Bytes=546)
3 0 TABLE ACCESS (BY IX ROWID) OF 'EMP' (Cost=2 Card=4 Bytes=28)
4 3 INDEX (RANGE SCAN) OF 'EMP_IX2' (NON-UNIQUE) (Cost=1 Card=4)

40 Custom presentation- or document control name


Ordinamento dei dati

 FULL-TABLE-SCAN + SORT
E’ l’unica possibilità quando la colonna (o le colonne) di
ordinamento non sono indicizzate o quando ammettono
valori NULL. L’ordinamento dei dati avviene utilizzando
la clausola ORDER BY.
 INDEX-RANGE-SCAN + TABLE ACCESS BY ROWID
Se le colonne di ordinamento sono indicizzate e non
ammettono valori NULL si può “pilotare” l’ordinamento
con l’uso di hint.

41 Custom presentation- or document control name


Esempio (1) - ordinamento dei dati

SELECT *
FROM dept
ORDER BY dname;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=4 Bytes=72)
1 0 SORT (ORDER BY) (Cost=3 Card=4 Bytes=72)
2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=4 Bytes=72)

42 Custom presentation- or document control name


Esempio (2) - ordinamento dei dati

SELECT /*+ INDEX_ASC(dept dept_ix1) */ *


FROM dept;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=4 Bytes=72)
1 0 TABLE ACCESS (BY IX ROWID) OF 'DEPT' (Cost=2 Card=4 Bytes=72)
2 1 INDEX (FULL SCAN) OF 'DEPT_IX1' (NON-UNIQUE) (Cost=1 Card=4)

43 Custom presentation- or document control name


Riepilogo

In questo paragrafo abbiamo visto:


 Utilizzo corretto degli indici
 I diversi costrutti SQL, le alternative

44 Custom presentation- or document control name

Potrebbero piacerti anche