DB2 10 Best Practices V1.3 – Angelo Sironi

4/19/2014
Best Practices Hints & Tips
e “Novità” SQL
A cura di Angelo Sironi
A.Sironi 2014
1
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi-row Fetch / multi-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
2
1
4/19/2014
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi
Multi-row Fetch / multimulti-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
3
Ipotesi
◦ Processore da 1.000 Mips
◦ Ignorato effetto MP
◦ Dati indicativi
SQL Statement
SET :h = CURRENT DATE
SELECT INTO :h
FETCH 1 riga
Multi-row FETCH 100 righe
A.Sironi 2014
Consumo di CPU
minimo (microsec
(microsec.)
microsec.)
Istruzioni
equivalenti
3
3.000
13
13.000
10
10.000
500
500.000
4
2
4/19/2014
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi
Multi-row Fetch / multimulti-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
5
Funzione
◦ Fornire informazioni sulla strategia di accesso ai dati
scelta dall’ottimizzatore
Tipo di accesso (es. guidato da uno o più indici)
Sequenza di join
Metodo di join
Ecc.
Invocazione
◦ SQL statico
Opzione EXPLAIN ( NO, YES, ONLY) del comando BIND
PACKAGE
Statement EXPLAIN PACKAGE (nuovo in DB2 10)
◦ SQL statico o dinamico
Statement EXPLAIN
PrePre-requisiti (minimi)
◦ Esistenza di una copia della tabella user.PLAN_TABLE
user
A.Sironi 2014
6
3
4/19/2014
EXPLAIN
PAKAGE
PAKAGE
COLLECTION
collection -name
package-name
VERSION version-name
COPY
copy-id
Provoca l’Explain di tutti gli statement del Package
◦ Il DB2 esternalizza in PLAN_TABLE una copia delle
informazioni sulle strategia di accesso esistenti in formato
interno
◦ Diversamente dal comando BIND EXPLAIN(ONLY), non viene
generata una nuova strategia di accesso
◦ Non viene effettuato un BIND
◦ Si applica solo a Package bound con DB2 V9 o successivi
A.Sironi 2014
7
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi
Multi-row Fetch / multimulti-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
8
4
4/19/2014
SQL Request
SQL Result
RELATIONAL DATA SERVICES
DATA MANAGER
Evaluates
STAGE 2
predicates
Evaluates
STAGE 1
(“sargable”)
predicates
BUFFER MANAGER
A.Sironi 2014
9
Efficienza
◦ Predicati Stage 1
◦ Indexable
◦ Adeguatamente supportati da indici
Stage 1
◦ Gestiti dal Data Manager nell’accesso al Buffer Pool
◦ Inibitori più comuni: presenza nei predicati di
Funzioni scalari (es. T1.C1 = SUBSTR(T2.C1,1,4) )
Espressioni (es. T1.C1 + :h1 = :h2 )
Mismatch di tipo dato (es. T1.C1 = :h1 con C1
SMALLINT e :h1 DECIMAL(7,0))
A.Sironi 2014
10
5
4/19/2014
Tecniche/costrutti da non usare nei predicati
◦ CASE Expression
◦ :hostvar1 = costante OR Colonna = :hostav2 .. ecc.
Tecniche tollerate (ottimizzabili esternamente)
◦ WHERE COL1 BETWEEN :hostvar1 AND :hostvar2
AND COL2 BETWEEN : hostvar3 AND :hostvar4
AND ecc.
◦ Uso di “BETWEEN” raccomandato al posto di
predicati del tipo
WHERE COL1 >= :hostvar1
AND COL1 <= :hostvar2
AND ecc.
◦ Eccezione: :hv BETWEEN
COL1 AND COL2
A.Sironi 2014
11
2,3 FETCH per OPEN (di cui una con SQLCODE=100)
Ca. 5.000 GETPAGE / OPEN – 3 millisec.
millisec. di CPU in media)
DECLARE CURS01 CURSOR FOR
SELECT ecc.
FROM TABLE_1 T1
INNER JOIN
TABLE_2 T2
ON … predicati di join …
WHERE T1.C1
= :H1
AND T1.C2
= :H2
AND ((CASE :H5 WHEN 0 THEN T1.C3 END = :H3
AND
CASE :H5 WHEN 0 THEN T1.C4 END = :H4 )
OR
(CASE :H3 WHEN 0 THEN T1.C5 = :H5 ) )
ORDER BY ecc.
A.Sironi 2014
12
6
4/19/2014
Caso 1:
1: sono noti i valori di ricerca di C3 e C4
DECLARE CURS01 CURSOR FOR
SELECT ecc.
FROM TABLE_1 T1
INNER JOIN
TABLE_2 T2
ON … predicati di join …
WHERE T1.C1
= :H1
AND T1.C2
= :H2
AND T1.C3
= :H3
AND T1.C4
= :H4
ORDER BY ecc.
A.Sironi 2014
Caso 2:
2: sono noti i valori di ricerca di C5
DECLARE CURS01 CURSOR FOR
SELECT ecc.
FROM TABLE_1 T1
INNER JOIN
TABLE_2 T2
ON … predicati di join …
WHERE T1.C1
= :H1
AND T1.C2
= :H2
AND T1.C5
= :H5
ORDER BY ecc.
A.Sironi 2014
7
4/19/2014
Flusso originale (semplificato)
OPEN CURS01
FETCH CURS01
Gestisci Riga
CLOSE CURS01
ecc.
A.Sironi 2014
15
Flusso modificato (semplificato)
Caso 1
IF …
OPEN CURS01A
FETCH CURS01A
Caso 2
OPEN CURS01B
Gestisci Riga
CLOSE CUSR01A
FETCH CURS01B
CLOSE CURS01B
ecc.
A.Sironi 2014
16
8
4/19/2014
Cardinalità della Tabella: 3,0 milioni
SELECT ecc.
INTO :H , …
FROM TABLE
WHERE C1 = :H1
AND ( '' = :HX OR
ID = :HID )
AND ( ( '' = :HY AND
0 = :HZ )
OR
( CX = :HX AND
CY = :HY ) )
Valori medi per singola esecuzione
◦ Elapsed Time
◦ Consumo di CPU
◦ Getpage
: 10,59 sec.
: 2,074 sec. (ca. 2 miliardi di istr.)
: 409.406
A.Sironi 2014
17
Cardinalità della Tabella: 7,5 milioni
SELECT
FROM
WHERE
AND
AND
AND
AND
AND
AND
AND
COUNT ( * ) INTO :H
TABLE
C1 = :H AND DATA BETWEEN :H AND :H
( C2 IN ( :H , :H ) )
( :H IN ( C3, C4, '
' ) )
( :H IN ( C5 , 0 ) )
( :H IN ( C6 , '
' ) )
( :H IN ( C7 , '
' ) )
( :H IN ( C8, C9,
'
( C10 <> 12345 OR ( C10 = 12345 AND
C11 <> ‘XXXXXXXXX' ))
' ) )
Valori medi per singola esecuzione
◦ Elapsed Time
◦ Consumo di CPU
◦ Getpage
A.Sironi 2014
: 7,097 sec.
: 4,432 sec. (ca. 4,5 miliardi di istr.)
: 193.443
18
9
4/19/2014
Soluzione raccomandata
◦ Del tutto simile alla precedente
◦ Più semplice, non dovendo gestire OPEN/CLOSE e ciclo
di FETCH
Si suddivide in due, tre o più casi, a seconda
della frequenza d’uso e della capacità di filtro,
usando dove possibile predicati di uguaglianza
◦ Caso 1:
1 predicati su C1, C2 (e C5 ?)
◦ Caso 2
2: predicati su C1, C2 e C6
◦ Caso 3:
3 ecc.
Invece dell’operatore CASE, si usino condizioni di
BETWEEN, ed eventualmente hint per REOPT
Riduzione del consumo di CPU attesa
Similmente per il caso 2B
◦ Uno o anche due ordini di grandezza
A.Sironi 2014
19
WITH TEMP1 AS (SELECT C1, C2, C3, ecc.
FROM TABLE
WHERE C1 = :H AND DATA BETWEEN :H AND :H
AND ( C2 IN ( :H , :H ) )
AND ( :H IN ( C3, C4, '
' ) )
AND ( :H IN ( C5 , 0 ) )
AND ( :H IN ( C6 , '
' ) )
AND ( :H IN ( C7 , '
' ) )
AND ( :H IN ( C8, C9,
'
' ) )
AND ( C10 <> 12345 OR ( C10 = 12345 AND
C11 <> ‘XXXXXXXXX' ))
),
TEMP2 AS (SELECT COUNT(*) AS CONTA FROM TEMP1)
SELECT T1.*, T2.CONTA
FROM TEMP1 T1, TEMP2 T2
A.Sironi 2014
20
10
4/19/2014
SELECT … omissis …
FROM TABLE_1 T1
LEFT OUTER JOIN
TABLE_2 T2
ON … omissis …
WHERE T1.C1 = COALESCE (CAST ( ? AS VARCHAR(8)), T1.C1 )
AND T1.C2 = COALESCE (CAST ( ? AS VARCHAR(5)), T1.C2 )
AND … omissis …
AND T1.END_DATE <= CURRENT TIMESTAMP
AND COALESCE ( T1.END_DATE , ( CURRENT TIMESTAMP + 1
SECOND ) ) > ( CURRENT TIMESTAMP )
Ambiente DRDA JDBC / ODBC
◦ Il DB2 non riesce ad usare in modo efficiente (Matching
Mode) eventuali indici su T1.C1 e/o T1.C2
◦ Ogni esecuzione della query provoca mediamente la
scansione di 17.000 pagine e un consumo di CPU di oltre
170 millisecondi (per Prepare, Open, 2-3 Fetch, Close)
A.Sironi 2014
21
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi
Multi-row Fetch / multimulti-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
22
11
4/19/2014
Problemi «logici» in presenza di NULL
◦
◦
◦
◦
Risultati potenzialmente errati
Maggiore complessità della codifica SQL
Inefficienze
Spazio disco e memoria
Non abusare nell’uso dei NULL
◦ Evitare di definire colonne come NULL-able, a meno
che non se ne possa proprio fare a meno
Attenzione:
Attenzione:
◦ NULL è il default!
A.Sironi 2014
D1:
23
Trovare i Fornitori che
è noto che forniscono
il Prodotto P1, ma di
certo non in una
quantità pari a 100
Q1a
SELECT
FROM
WHERE
AND
R1a
DISTINCT FX.COD_F
FORNITORI FX
FX.PRODOTTO = 'P1'
100 NOT IN
( SELECT FY.QTA
FROM FORNITORI FY
WHERE FY.COD_F = FX.COD_F
AND FY.PRODOTTO = 'P1') ;
A.Sironi 2014
12
4/19/2014
D1:
Trovare i Fornitori che
è noto che forniscono
il Prodotto P1, ma di
certo non in una
quantità pari a 100
Q1b
SELECT
FROM
WHERE
AND
R1b
DISTINCT FX.COD_F
FORNITORI FX
FX.PRODOTTO = 'P1'
NOT EXISTS
( SELECT FY.QTA
FROM FORNITORI FY
WHERE FY.COD_F = FX.COD_F
AND FY.PRODOTTO = 'P1'
AND FY.QTA = 100 ) ;
A.Sironi 2014
Q2a (tautologia?)
SELECT
FROM
WHERE
OR
*
FORNITORI
QTA = 100
QTA <> 100
R2a
Q2t (tautologia!)
SELECT
FROM
WHERE
OR
OR
*
FORNITORI
QTA = 100
QTA <> 100
QTA IS NULL
R2t
A.Sironi 2014
13
4/19/2014
Q3
SELECT AVG(SALARIO) + AVG(COMM) AS AVG_SAL_1
, AVG(SALARIO+COMM) AS AVG_SAL_2
FROM FORNITORI
A.Sironi 2014
Esempio
CREATE TABLE TEST
( KEY INTEGER NOT NULL,
VALID_FROM TIMESTAMP NOT NULL,
VALID_TO
TIMESTAMP )
Trovare il record con KEY = :h valido ora
SELECT * FROM TEST
WHERE VALID_FROM <= CURRENT TIMESTAMP
AND (VALID_TO >= CURRENT TIMESTAMP OR
VALID_TO IS NULL)
Esistono un certo numero di varianti della
soluzione precedente
◦ Alcune decisamente inefficienti…
A.Sironi 2014
28
14
4/19/2014
SELECT … omissis …
FROM TABLE_1 T1
LEFT OUTER JOIN
TABLE_2 T2
ON … omissis …
WHERE T1.C1 = COALESCE (CAST ( ? AS VARCHAR(8)), T1.C1 )
AND T1.C2 = COALESCE (CAST ( ? AS VARCHAR(5)), T1.C2 )
AND … omissis …
AND T1.END_DATE <= CURRENT TIMESTAMP
AND COALESCE ( T1.END_DATE , ( CURRENT TIMESTAMP + 1
SECOND ) ) > ( CURRENT TIMESTAMP )
La colonna END_DATE, essendo NULLable,
NULLable, non può
essere parte della chiave di univocità
Il DB2 non riesce ad usare in modo efficiente un
eventuale indice sulla colonna END_DATE
A.Sironi 2014
29
NULL
◦ Non è un valore della colonna
◦ È un indicatore associato alla colonna
◦ Ogni colonna NULL-able richiede un byte in più
Nel tablespace
In ogni eventuale indice di cui risulta parte della chiave
Su disco e nei buffer pool
A.Sironi 2014
30
15
4/19/2014
Colonne Carattere
◦ Usare una stringa di blank
SE VARCHAR, impostare LL = 0
Colonne DATE e TIMESTAMP usate per
delimitare intervalli di validità
◦ Esempio per datatype DATE
LOW-END = valore a scelta / default ‘01.01.0001’
HIGH-END = ‘30.12.9999’ (standard Java e SQL
ISO/ANSI Temporal Support) oppure ‘31.12.9999’
◦ Reperimento del record valido ora
SELECT * FROM TEST
WHERE VALID_FROM <= CURRENT TIMESTAMP
AND VALID_TO > CURRENT TIMESTAMP
A.Sironi 2014
Il DB2 10 per z/OS introduce il supporto dello
standard ANSI/ISO SQL per le costanti datetime
Esempi della sintassi
◦
◦
◦
◦
◦
◦
◦
◦
◦
31
DATE '1977-01-18'
-- valid date (ISO format)
DATE '18.01.1977'
-- valid date (EUR format)
DATE '0000-01-18'
-- invalid date (bad year)
DATE '2010-02-29'
-- invalid date (bad day)
TIME '24:00:00'
-- valid time (JIS, ISO format)
TIME '24:00:01'
-- invalid time (bad hour)
TIME '00.00.00'
-- valid time (EUR format)
TIME '12:01 AM'
-- valid time (USA format)
TIMESTAMP '2007-05-14 11:55:00.1234' -- valid
(space and colons)
Raccomandazione:
Raccomandazione: specificare
◦ DATE ‘2010‘2010-0808-06’ invece di
◦ DATE(‘2010
DATE(‘2010(‘2010-0808-06’)
per migliorare la portabilità e, forse, anche le prestazioni
Evitare codifiche del tipo WHERE CHAR(data, ISO) = :h
A.Sironi 2014
32
16
4/19/2014
Prima del DB2 10, il formato del tipo dato
TIMESTAMP era fisso e forniva una precisione al
microsecondo (10-6 secondi)
Con il DB2 10, l’utente può definire la precisione
che preferisce
◦ minima = 0 (precisione al secondo)
◦ massima = 12 (precisione al picosecondo = 10-12 secondi)
Esempi:
Esempi:
◦
◦
◦
◦
TS1 TIMESTAMP(0)
TS2 TIMESTAMP(9)
TS3 TIMESTAMP(12)
CURRENT TIMESTAMP(12)
La lunghezza della colonna varia di conseguenza
Per i dettagli:
dettagli: si veda il Redbook SG24SG24-7892
A.Sironi 2014
33
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi
Multi-row Fetch / multimulti-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
34
17
4/19/2014
Premessa
◦ Batch = elaborazione di massa
◦ Elaborazione di massa richiama in modo connaturale
“elaborazione di insiemi / set processing”
Set Processing
Uno dei cardini del Modello Relazionale
Fonte di continui progressi funzionali e prestazionali
nell’implementazione dei sistemi e del linguaggio SQL
Le varie forme di Prefetch e Block Fetch
Query Parallelism
Multi-row fetch
OLAP Specification
Inibitori…
◦ Applicazioni Batch che pretendono di operare come
applicazioni OLTP
A.Sironi 2014
35
Sintomi
◦ Elaborazione guidata da file sequenziale
◦ Elevato numero di SELECT INTO e/o elevato numero
di OPEN CURSOR con pochissime FETCH per OPEN
◦ Spesso associato ad un limitato uso degli operatori
relazionali
◦ Non infrequente un elevato numero di accessi a
tabelle di pochi record
Motivazioni addotte
◦ Riutilizzo del codice
A.Sironi 2014
36
18
4/19/2014
Caso tipico di inapplicabilità
◦ Elaborazione guidata da file sequenziale
SQL_CALL
-------SELECT
SELECT
SELECT
OPEN
FETCH
CLOSE
SELECT
OPEN
FETCH
SELECT
CLOSE
STMT£
SQL
CPUPCT
------- --------- ------0005103 13676256 47.77%
0004771 11320907 40.53%
0003826
1641730
7.82%
0004846
221613
2.51%
0004874
795415
.96%
0005048
221613
.21%
0004548
12495
.11%
0004334
1265
.03%
0004362
16049
.02%
0004035
1871
.00%
0004615
1265
.00%
INDB2_TIME
-----------01:40:18.094
19:49.657642
06:40.676105
00:22.988164
00:08.288251
00:01.728707
00:11.031098
00:04.849223
00:00.185866
00:01.110174
00:00.009167
INDB2_CPU
GETPAGE
------------ -------02:56.577296 8941179
02:29.812458 8348682
00:28.905415 3647381
00:09.285109
638606
00:03.549874
0
00:00.788970
0
00:00.429413
55388
00:00.115000
8823
00:00.087877
0
00:00.028994
878
00:00.004745
0
A.Sironi 2014
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦
◦
◦
37
MultiMulti-row Fetch / multimulti-row Insert
Query Parallelism
Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦
◦
◦
◦
◦
◦
Fetch 1 Row Only;
Only; Optimize For 1 Row
Nuovi costrutti SQL
Generazione di Chiavi di Univocità: Oggetto SEQUENCE
Temporary Table
Stored Procedure
Extended Indicator Variable
A.Sironi 2014
38
19
4/19/2014
Integrato in alcuni programmi di “utilità
“utilità”
utilità”
◦ Es. DSNTIAUL
◦ Operano con valore di default = 100
Ogni FETCH legge 100 righe
◦ Punto di massimo vantaggio
Vantaggi
◦ Mediamente, 50% ca. di riduzione del consumo di
CPU
Su letture di milioni di record per OPEN di cursore
PrePre-requisiti
◦ Set Processing
◦ Modifiche al codice applicativo
A.Sironi 2014
39
Un unico statement di INSERT può inserire una
molteplicità di righe (<32,768) da un array
Opzioni:
Opzioni:
◦ ATOMIC: se va male l’inserimento anche di una sola riga,
tutto lo statement fallisce
◦ NOT ATOMIC: ciascuna riga trattata separatamente dale
altre
Lo statement GET DIAGNOSTICS fornisce
informazioni diagnostiche per ciascuna riga per
la quale l’inserimento non è andato a buon fine
L’SQLCODE indica se
◦ L’inserimento non è andato a buon fine per nessuna riga
◦ L’inserimento è andato a buon fine per tutte le righe
◦ L’inserimento non è andato a buon fine per almeno una
riga
A.Sironi 2014
40
20
4/19/2014
Ci si può aspettare fino al 40% di riduzione
del consumo di CPU
◦ Minore se maggiore è il numero delle colonne e/o il
numero degli indici
◦ Maggiore al crescere del numero delle righe inserite
per statement di Insert
A.Sironi 2014
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦
◦
◦
41
MultiMulti-row Fetch / multimulti-row Insert
Query Parallelism
Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioneidei consumi di CPU
◦
◦
◦
◦
◦
◦
Fetch 1 Row Only;
Only; Optimize For 1 Row
Nuovi costrutti SQL
Generazione di Chiavi di Univocità: Oggetto SEQUENCE
Temporary Table
Stored Procedure
Extended Indicator Variable
A.Sironi 2014
42
21
4/19/2014
PrePre-requisiti
◦ Elaborazione per insiemi / query “gravosa”
◦ Tabelle partizionate
◦ Disponibilità di risorse hw (macchina non satura)
Attivazione
◦ SQL statico
Attivabile al BIND tramite opzione DEGREE (ANY)
◦ SQL dinamico
Attivabile tramite comando SQL SET CURRENT DEGREE =‘ANY’
(oppure :hostvar impostata al valore “ANY”)
Vantaggi
◦ Parte del consumo (non solo DRDA) scaricato su zIIP
◦ Miglioramento dei tempi di esecuzione
◦ Trasparenza applicativa
Cfr.
Cfr. Riferimenti [4]
A.Sironi 2014
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦
◦
◦
43
MultiMulti-row Fetch / multimulti-row Insert
Query Parallelism
Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazione dei consumi di CPU
◦
◦
◦
◦
◦
◦
Fetch 1 Row Only;
Only; Optimize For 1 Row
Nuovi costrutti SQL
Generazione di Chiavi di Univocità: Oggetto SEQUENCE
Temporary Table
Stored Procedure
Extended Indicator Variable
A.Sironi 2014
44
22
4/19/2014
SQL_CALL
-------FETCH
OPEN
SELECT
FETCH
FETCH
OPEN
OPEN
CLOSE
STMT£
------0006943
0004053
0007088
0007144
0007120
0005797
0006305
0006588
SECT£
----00002
00002
00011
00004
00003
00003
00004
00002
SQL
CPUPCT
--------- ------36380455 61.43%
403910 26.34%
403910
3.83%
807836
2.63%
807828
2.55%
403910
.79%
403918
.74%
403910
.57%
INDB2_TIME
-----------03:14.944890
01:28.554185
00:12.454234
00:08.712145
00:08.419207
00:02.534090
00:02.356381
00:01.847810
INDB2_CPU
-----------02:33.245450
01:05.707429
00:09.571059
00:06.562709
00:06.373773
00:01.974218
00:01.845975
00:01.436934
La OPEN 4053 e le FETCH 6943 operano su una
tabella di 14.966 righe
◦ Oltre 36,3 milioni di Fetch
◦ Mediamente,
Mediamente ogni riga viene letta ca. 2.430 volte!
volte
Evitabile,
Evitabile, senza stravolgere l’architettura
dell’applicazione?
dell’applicazione?
A.Sironi 2014
45
Letture duplicate: evitabili?
evitabili?
◦ Sort del file guida sulla base dei criteri di ricerca
Se i criteri di ricerca non cambiano, i dati sono già
nelle aree di memoria del programma
1234fr345
3245pr543
5639tr321
……
A.Sironi 2014
1847
1847
1849
…
bdf5678798
jkefhy7980
kjfh769i89j
….
oldkey = 0000
newkey = 1234
IF oldkey <> newkey
do
EXEC SQL
SELECT C1, C2, C4
INTO :c1, :c2, :c3
FROM T1
WHERE K = :newkey
** test SQLCODE
MOVE newkey to oldkey
enddo
46
23
4/19/2014
E se non è possibile prepre-ordinare il file guida
sulla chiave di ricerca?
ricerca?
Alternative
1. Provare comunque ad utilizzare la tecnica appena
indicata
anche in assenza di ordinamento ottimale
2. Pre-caricare la tabella in memoria e effettuare
ricerche binarie
A.Sironi 2014
Disponibile in Cobol da diversi lustri
◦ SEARCH
◦ SEARCH ALL
47
- ricerca seriale (Attenzione ai costi!)
– ricerca binaria
Consumi
◦ Per tabelle di cardinalità > 1000, fino a due ordini di
grandezza di risparmio rispetto ad una SELECT INTO
PrePre-requisiti
1. La tabella deve presentare un criterio di univocità
2. Deve essere caricata in memoria ordinata secondo tale
criterio
3. La ricerca deve prevedere predicati di uguaglianza in
AND logico su tutte le colonne della chiave di univocità
4. La dimensione della tabella deve essere compatibile
con al disponibilità di memoria
A.Sironi 2014
48
24
4/19/2014
http://shaddy-ethical-hacking.blogspot.it/2013/05/a-c-program-to-binary-search-any-element.html
A.Sironi 2014
49
Se la ricerca
◦ Non qualifica tutte le colonne della chiave di
univocità
◦ Qualifica una o più colonne con predicato di range
◦ Deve reperire più di una riga
Opzioni
◦ Ricerca binaria su valore minimo del predicato di
range o della colonna priva di predicato (se
se noto
…); oppure …
◦ Assegnazione di una chiave di univocità surrogata
(v. esempio alla pagina successiva)
A.Sironi 2014
50
25
4/19/2014
Caso tipico
◦ Ricerca del valore corrente ad una certa data
Tasso di interesse
Costo o prezzo di vendita di un articolo
Ecc.
Struttura dati essenziale
◦
◦
◦
◦
KEY
INI_VAL
END_VAL
Valore
– Chiave naturale
– Data di inizio validità
- Data di fine validità
- Dato di interesse
Ricerca del VALORE in vigore alla data di
interesse
SELECT VALORE FROM T1 WHERE KEY = ?
AND INI_VAL <= ? AND END_VAL > ?
A.Sironi 2014
51
Il programma carica in memoria il risultato
della query seguente
SELECT KEY
, ROW_NUMBER()
OVER(PARTITION BY KEY
ORDER BY END_VAL ASC )
AS ROWNUM
, INI_VAL, END_VAL, VALORE
DESC
FROM TABLE
ORDER BY KEY, 2
A.Sironi 2014
52
26
4/19/2014
Il programma,
programma, invece di interrogare il DB2
◦ esegue una ricerca binaria per uguaglianza sul valore
di KEY di interesse e RWNUM =1
◦ Prosegue con una ricerca sequenziale del dato di
interesse (predicati temporali) fino a rottura di KEY
Efficienza garantita se il numero medio di righe per
chiave naturale (KEY, nell’esempio)
nell’esempio) è almeno di un
ordine di grandezza inferiore alla cardinalità di KEY
◦ Es. Card di KEY = 1.000; Table Card = 10.000
A.Sironi 2014
53
Esempio
◦ Tabella con chiave di univocità su (C1, C2, C3)
◦ Esigenza:
Reperire tutte le righe on valori noti per C1 e C3
◦ Caricamento in memoria da tabella DB2 tramite
SELECT * FROM
(SELECT T.*
, ROW_NUMBER() OVER(PARTITION BY C1,C3
ORDER BY C2)
AS ROW_NUM
FROM TABC123 T ) AS X
ORDER BY C1, C3, ROW_NUM
Note:
1.
2.
(C1, C3, ROW_NUM) è chiave di univocità
Tecnica applicabile anche se (C1, C2, C3) non è chiave di univocità
A.Sironi 2014
54
27
4/19/2014
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi
Multi-row Fetch / multimulti-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row e linguaggio SQL
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
55
Fetch First n Rows Only
◦ Indica al DB2 che l’applicazione è interessata solo
alle prime n righe dell’answer set
Originariamente utilizzabile solo nell’outer SELECT
Ora (dal DB2 9) utilizzabile anche nelle sub-SELECT
Fetch First 1 Row
◦ Utilizzare nelle SELECT INTO che potrebbero
restituire più di una riga
◦ Utilizzare nella definizione dei cursori dai quali si
leggerà sempre solo la prima riga
Trasformare questi cursori in SELECT INTO
◦ Utilizzare quando la SELECT INTO è interessata alla
riga più recente o più vecchia, evitando la subSelect
A.Sironi 2014
56
28
4/19/2014
SELECT ……
FROM MYTABLE A
WHERE A.COL1 = :H1
AND …
AND A.COLX = ( SELECT MAX ( B.COLX )
FROM MYTABLE B
WHERE B.COL_1 = :H1
AND … )
SELECT ……
FROM MYTABLE A
WHERE A.COL1 = :H1
AND …
ORDER BY COLX DESC
FETCH FIRST 1 ROWS ONLY
A.Sironi 2014
57
Optimize For n Row
◦ Un’indicazione all’Ottimizzatore per privilegiare la strategia
di accesso meno costosa per il reperimento delle prime n
righe
◦ L’applicazione può comunque recuperare tutte le righe di
interesse dell’answer set
Optimize For 1 Row (modifiche del DB2 10)
◦ Simile al comportamento pre DB2 10, ma il DB2 evita di
prendere in considerazione qualunque strategia di accesso,
anche se meno costosa, che comporti una fase di sort
◦ La strategia scelta può risultare più costosa delle attese
◦ L’Apar PM56845 permette di operare come pre DB2 10
◦ Alternativa suggerita, se non si usa l’opzione dell’apar
PM56845
OPTIMIZE FOR 2 ROWS
A.Sironi 2014
58
29
4/19/2014
Permette di condizionare l’esecuzione di Insert e
Update di una tabella a partire da un elenco di
variabili o un array di variabili
◦ Quando le condizioni imposte sono verificate, si esegue
l’Update
◦ Quando le condizioni non sono verificate, si esegue
l’Insert
◦ Provoca l’esecuzione di eventuali Trigger di Update /
Insert
◦ La sequenza di esecuzione di Update / Insert può avere
un impatto sulle prestazioni
Questa implementazione è meno potente di uella
resa disponibile dal DB2 for LUW, che permette
◦ Una subselect come input all’operazione di Merge
◦ L’esecuzione condizionata di Update, Insert e Delete
A.Sironi 2014
59
MERGE INTO items AS T
USING (VALUES (:item_id, :qty))
AS N(id, qty)
ON T.id = N.id
WHEN MATCHED THEN
UPDATE SET qty_on_hand = T.qty_on_hand +
N.qty,
T.upsert_ts = current timestamp
WHEN NOT MATCHED THEN
INSERT (id, qty_on_hand, upsert_ts) VALUES
(N.id, N.qty, current timestamp)
Si veda un esempio con un array come input in
Materiale di Riferimento [3]
A.Sironi 2014
60
30
4/19/2014
Il DB2 V8 ha introdotto SELECT From INSERT
Il DB2 V9 ha aggiunto SELECT From MERGE,
UPDATE, DELETE
◦ FROM data-change-table-reference
A.Sironi 2014
61
SELECT FROM INSERT
◦ Già disponibile con il DB2 V8
Esempio
SELECT id, qty_on_hand, upsert_ts, row_nr
FROM FINAL TABLE
(INSERT INTO items ( id, qty_on_hand)
INCLUDE (row_nr SMALLINT)
VALUES (101, 100, 1)
,(102, 200, 2))
ORDER BY row_nr;
A.Sironi 2014
62
31
4/19/2014
SELECT FROM UPDATE
SELECT id, qty_on_hand, upsert_ts
FROM FINAL TABLE
(UPDATE
SET
,
WHERE
items
qty_on_hand = qty_on_hand + 100
upsert_ts = current timestamp
id = 12345) ;
SELECT FROM DELETE
SELECT id, qty_on_hand, upsert_ts
FROM OLD TABLE
(DELETE FROM items
WHERE id = 12345) ;
A.Sironi 2014
63
SELECT * FROM FINAL TABLE
( MERGE INTO items AS T
USING (VALUES (:item_id, :qty)) AS N(id, qty)
ON T.id = N.id
WHEN MATCHED THEN
UPDATE
SET qty_on_hand = T.qty_on_hand + N.qty,
T.upsert_ts = current timestamp
WHEN NOT MATCHED THEN
INSERT (id, qty_on_hand, upsert_ts)
VALUES (N.id, N.qty, current timestamp)
)
A.Sironi 2014
64
32
4/19/2014
TRUNCATE table
◦ Un’alternativa efficace ed efficiente a
DELETE FROM table
LOAD REPLACE con input vuoto (dummy)
◦ Ise la tabella è una base table, vengono TRUNCATEd
anche eventuali porzioni di tipo LOB e XML, e tutti
gli indici associati
Sintassi
A.Sironi 2014
65
DROP STORAGE (default)
◦ Tutto lo spazio disco assegnato alla tabella viene
liberato e reso disponibile alla medesima tabella o ad
altre tabelle residenti nel medesimo Tablespace
REUSE STORAGE
◦ Tutto lo spazio disco assegnato alla tabella viene
svuotato, ma continua ad essere asegnato alla tabella
IGNORE DELETE TRIGGERS (default)
RESTRICT WHEN DELETE TRIGGERS
◦ Auto-esplicativo
◦ Restituisce un errore se sulla tabella è definito almeno
un Trigger di Delete
IMMEDIATE
◦ ROLLBACK non ha effetto; se omesso, in caso di
ROLLBACK viene ripristinata la situazione iniziale
A.Sironi 2014
66
33
4/19/2014
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi
Multi-row Fetch / multimulti-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
67
Temporary Table
◦ Utili quando si ha la necessità di memorizzare delle
informazioni solo per la durata della transazione
Due tipi di Temporary Table
◦ CGTT (C
Created Global Temporary Table)
No logging, no locking
◦ DGTT (D
Declared Global Temporary Table)
«Limited logging», «limited locking»
A.Sironi 2014
68
34
4/19/2014
Caratteristiche e limiti
◦ Definizione tramite comando CREATE GLOBAL
TEMPORARY TABLE
No valori di default diversi da NULL
No LOB o ROWID
Nessun tipo di constraint (Ref. Integrity, ecc,)
◦
◦
◦
◦
◦
◦
Struttura condivisa
No logging
No locking
Nessuna possibilità di definire indici
Update non permessi
Delete permessi solo se privi della clausola WHERE
Istanziazione
◦ Copia privata istanziata al primo riferimento da uno
statement SQL di Delete, Insert, SELECT o OPEN Cursor
A.Sironi 2014
69
Commit
◦ If no pending «WITH HOLD» open cursor, all rows
of every temporary table of the application
process are deleted
If also RELEASE(COMMIT) in effect, all logical work
files for every temporary table are also deleted
Rollback
◦ all rows and all logical work files of every
temporary table of the application process are
deleted.
A.Sironi 2014
70
35
4/19/2014
Uso
◦ Quando si ha necessità di memorizzare dati solo per la
durata di un processo applicativo e non si ha necessità
di condividere la struttura della tabella
Definizione
◦ Tramite comando DECLARE GLOBAL TEMPORARY TABLE
L’istanza è nota solo all’applicazione che l’ha definita
La definizione non è memorizzata nel Catalogo DB2 ed
esiste solo finchè è attivo il pocesso applicativo che l’ha
creata
Implicitamente (o esplicitamente) qualificata con SESSION
Istanziazione
◦ Una copia vuota quando viene eseguito il comando
DECLARE GLOBAL TEMPORARY TABLE
A.Sironi 2014
71
Opzioni di COMMIT
◦ DELETE ROWS
Applicata se nessun cursore con WITH HOLD è aperto
sulla DGTT
◦ PRESERVE ROWS
◦ DROP TABLE
Applicata se nessun cursore con WITH HOLD è aperto
sulla DGTT
Molti meno vincoli rispetto alle CGTT
◦
◦
◦
◦
◦
Colonne con valori di default
Possibilità di definire indici
Supporto di UPDATE e DELETE con predicati
Supporto di SAVEPOINT
Ecc.
A.Sironi 2014
72
36
4/19/2014
Definizione
Created GTT
Declared GTT
DBA tramite CREATE
Utente tramite DECLARE
Memoria nel Catalogo
Si
No
Valori di default
Solo NULL
Si
Colonne LOB e ROWID Non permesse
Permesse
Struttura
Condivisa
Non condivisa
Logging
No
Limitato
Locking
No
Limitato
Definizione di indici
Non permessa
Permessa
SQL Update
Non permesso
Permesso
SQL Delete
Solo senza WHERE
Permesso
Supporto SAVEPOINT
No
Si
Opzioni di Commit
Nessuna - righe
DELETE / PRESERVE ROWS
cancellate in assenza di
DROP TABLE
cursore WITH HOLD aperto
A.Sironi 2014
73
Statement SQL: Costi di riferimento
EXPLAIN: Prevenire è meglio che curare
Ricerche generiche: Tecniche da evitare e loro
alternative
NULL: Uso e abuso
Architettura Batch e ottimizzazioni
◦ Multi
Multi-row Fetch / multimulti-row Insert
◦ Query Parallelism
◦ Ricerca binaria (aka
(aka dicotomica)
Ulteriori ottimizzazioni dei consumi di CPU
◦ Fetch 1 Row Only;
Only; Optimize For 1 Row
◦ Temporary Table
◦ Extended Indicator Variable
A.Sironi 2014
74
37
4/19/2014
Il dilemma degli sviluppatori
◦ Come predisporre del codice capace di gestire tutte
le operazioni di UPDATE e INSERT di una tabella,
non sapendo fino al momento dell’esecuzione quali
colonne inserire o aggiornare.
Tutti gli approcci in uso sono insoddisfacenti
◦ Costruzione dinamica dello statement SQL
◦ Codifica in anticipo di tutte le possibili
combinazioni di statement SQL
◦ Codifica di un unico statement SQL in grado di
gestire tutte le possibili combinazioni di colonne
A.Sironi 2014
75
Permette di specificare
1. Che per una o più colonne oggetto di Insert,
Update o Merge non viene fornito nessun valore
2. Come il DB2 deve trattare i valori mancanti
L’uso può essere abilitato
◦ A livello del Package, tramite l’opzione
EXTENDEDINDICATOR dei comandi BIND e REBIND
PACKAGE
◦ Per l’SQL dinamico, tramite l’attributo “WITH
EXTENDED INDICATORS” dello statement PREPARE
NOTE
◦ L’impostazione modifica iil risultato dell’esecuzione
dello statement SQL
A.Sironi 2014
76
38
4/19/2014
Quando un’Indicator Variabile è usata in input, il
valore assegnato condiziona il comportamento del
DB2, come segue:
◦ -5
Valore di Default, se Extended Indicator Variable abilitata
NULL, in caso contrario
◦ -7
Non impostata (= come se non presente nello statement), se
Extended Indicator Variable abilitata
NULL, in caso contrario
◦ -1, -2, -3, -4, or -6
NULL
◦ 0 o qualunque valore positivo
La variabile contiene un vaore valido
I valori diversi da -1 non vengono assegnati dal DB2
a (Extended) Indicator Variable usate in output
A.Sironi 2014
77
Per INSERT
◦ I valori -5 e -7 conducono allo stesso risultato,
perché la semantica dell’Insert è quella di impostare
la colonna a NULL o inserire un valore di default (a
seconda della definizione adottata) per ogni
colonna alla quale non è stato assegnato un valore
Per UPDATE o MERGE UPDATE
◦ Il valore -5 provoca l’aggiornamento della colonna
al valore di default
◦ Il valore -7 fa sì che la colonna non venga
aggiornata
A.Sironi 2014
78
39
4/19/2014
A.Sironi 2014
79
Fetch 1 Row Only;
Only; Optimize For 1 Row
MultiMulti-row Fetch / multimulti-row Insert
Query Parallelism
Ricerca binaria (aka
(aka dicotomica)
Nuovi costrutti SQL
Generazione di Chiavi di Univocità: Oggetto
SEQUENCE
◦ Temporary Table
◦ Stored Procedure
◦ Extended Indicator Variable
◦
◦
◦
◦
◦
Intervalli di Validità e SQL “Temporal
“Temporal Support”
Support”
A.Sironi 2014
80
40
4/19/2014
Permette di reperire più righe dell’answer
dell’answer set con
una sola Fetch
Garantisce un miglioramento significativo delle
prestazioni, specialmente per applicazioni DRDA
◦ Un solo viaggio in rete (on in Cross-Memory, se locale)
◦ Quando si devono reperire o inserire grandi quantità di
dati
◦ La Distributed Block Fetch aveva già permesso di
migliorare il costo di alcune FETCH, ma non delle INSERT
◦ Possibile sostanziale riduzione del consumo di CPU
anche per applicazioni non-DRDA
Richiede la definizione di array nei programmi
◦ FETCH verso un array, oppure …
◦ INSERT da un array
Posizionamento al Rowset usato per‘navigare’
per‘navigare’
A.Sironi 2014
81
ROWSET
◦ Un gruppo di righe restituito da una singola operazione
di FETCH
◦ Abilitato sulla dichiarativa del Cursore
EXEC SQL DECLARE C1 CURSOR
WITH ROWSET POSITIONING
FOR SELECT * FROM EMP;
◦ Dimensione del set dichiarata dal programma sulla Fetch
FETCH FIRST ROWSET FROM C1
FOR x ROWS INTO ...
Dimensione massima: 32,767 righe
◦ Posizionamento del ROWSET (pagine successive)
◦ Nell’uso di un cursore multi-row, il programma può
mescolare Fetch di una sola riga con Fetch multi-row
A.Sironi 2014
82
41
4/19/2014
Fetch delle PRIME 100 righe
FETCH FIRST ROWSET FROM C1
FOR 100 ROWS INTO ...
Fetch delle 50 righe SUCCESSIVE partendo dalla posizione
corrente del cursore
FETCH ROWSET FROM C1
FOR 50 ROWS INTO ...
Fetch del ROWSET precedente
FETCH PRIOR ROWSET FROM C1
FOR 50 ROWS INTO ...
Fetch di 20 Righe a partire dalla Riga 10
FETCH ROWSET STARTING AT ABSOLUTE 10 FROM C1
FOR 20 ROWS INTO ...
Quando la Fetch restituisce un numero di righe inferiore a
quanto righiesto,
righiesto, il DB2 restituisce le righe rimaste insieme
all’SQLCODE +100
A.Sironi 2014
83
La multimulti-row Fetch richiede l’uso di array di
variabili host
◦ Tutti gli elementi di un array contengono un valore
proveniente dala medesima colonna
◦ Gli array possono essere referenziati solo da una multirow FETCH o da una multi-row INSERT
◦ In generale, gli array non possono essere array di
strutture
Esempio Cobol:
01 OUTPUT-VARS.
05 LASTNME OCCURS 10 TIMES.
49 LASTNME-LGTH
PIC S9(4) USAGE COMP.
49 LASTNME-DATA
PIC X(50).
05 EMPNO
PIC S9(9) COMP-4 OCCURS 10 TIMES.
………..
EXEC SQL FETCH FIRST ROWSET FROM C1 FOR 10 ROWS
INTO :LASTNME, :EMPNO
A.Sironi 2014
84
42
4/19/2014
Dopo l’esecuzione di una multimulti-row FETCH, il
cursore è posizionato su TUTTE le righe del
ROWSET corrente
Aggiornamento/cancellazione
Aggiornamento/cancellazione dell’intero ROWSET
UPDATE T1
SET C1 = 5
WHERE CURRENT OF CURSOR1
DELETE FROM T1
WHERE CURRENT OF CURSOR1
Aggiornamento/cancellazione
Aggiornamento/cancellazione di una specifica riga
del ROWSET
UPDATE T1
SET C1 = 5
WHERE CURRENT OF CURSOR1
FOR ROW 4 OF ROWSET
DELETE FROM T1
WHERE CURRENT OF CURSOR1
FOR ROW 4 OF ROWSET
A.Sironi 2014
85
E’ stata misurata una riduzione del consumo
di CPU fino al 50%
◦ Il guadagno ottimale si ha a circa 100 righe per
Fetch
Il beneficio si riduce con un elevato numero di colonne
◦ Guadagno trascurabile con meno di 10 righe per
Fetch
MultiMulti-Row Fetch con DSNTIAUL V8 e versioni
successive
◦ Nuovo default: 100 Righe per Fetch
L’utente Uspuò impostare un valore diverso
◦ Molto probabile una riduzione del consumo di CPU
di circa il 50% quando si rperiscono milioni di righe
A.Sironi 2014
86
43
4/19/2014
Per determinare quante righe sono state aggiornate da uno
statement di UPDATE
Per gestire una molteplicità di errori SQL durante una
Insert NOT ATOMIC multimulti-row
◦ GET DIAGNOSTICS :rcount = ROW_COUNT;
◦ GET DIAGNOSTICS :numerrors = NUMBER;
◦ Poi, si proceda con un loop per eseguire lo statement che segue
per il numero degli errori
GET DIAGNOSTICS CONDITION :i :retstate = RETURNED_SQLSTATE
Per reperire tutte le infromazioni diagnostiche disponibili
per uno statement SQL
◦ GET DIAGNOSTICS :diags = ALL STATEMENT
◦ Esempio di output in :diags
Number=1; Returned_SQLSTATE=02000;
DB2_RETURNED_SQLCODE=+100;
Vengono restituite ulteriori informazioni per tutti gli elementi applicabili
e tutte le condizioni
I vari elementi sono separati da un punto e virgola
A.Sironi 2014
A.Sironi 2014
87
88
44
4/19/2014
[1] SG24-7892 DB2 10 for z/OS Technical Overview,
Overview December
2010
[2] SG24-7942 DB2 10 for z/OS Performance Topics,
Topics June 2011
[3] IBM DB2 for z/OS Best Practices Web Page at
www.ibm.com/developerworks/data/bestpractices/db2zos/
[4] Adrian Collett, Need to Cut Costs? Time to Go Parallel on a
zIIP?
zIIP? , http://www.idug.org/p/cm/ld/fid=97&tid=88&stid=92
A.Sironi 2014
89
45