MainframeSupports
tip uge 2/2002:

Jeg ved af gode grunde ikke, hvor mange af jer, der kender til de såkaldte global temporary tables i DB2. Da jeg læste om dem første gang var mit indtryk, at det var ret ubrugeligt. Nu har jeg endelig fundet et anvendelsesområde, så det skal du kære læser straks belemres med.

Lad mig starte med ulemperne. Et global temporary table kan kun indeholde data i samme unit of work. Disse data kan ikke deles med andre units of work og dermed er dataene i tabellen dine helt private. Du kan ikke lave UPDATE mod et global temporary table.

Og nu til et konkret eksempel. Forestil dig, at du i et SQL-kald skal benytte den samme subselect to eller flere gange. Denne subselect indeholder en WHERE-clause, der ofte ændres i, og i øvrigt resulterer den i et meget begrænset antal rækker i forhold til den tabel, subselect'en læser fra. Det oprindelige SQL-kald ser måske således ud:

SELECT *
FROM TABLE_A TA, TABLE_B TB
WHERE TA.COLUMN_A IN
( SELECT COLUMN_X FROM TABLE_X
  WHERE COLUMN_Y = 'DELTA'
) AND TB.COLUMN_B IN
( SELECT COLUMN_X FROM TABLE_X
  WHERE COLUMN_Y = 'DELTA'
) AND TA.JOIN_COLUMN = TB.JOIN_COLUMN

Lad os nu optimere det. Først og fremmest skal du lave et global temporary table, der indeholder den kolonne, som din subselect returnerer. Dette gøres en eneste gang på følgende måde:

CREATE GLOBAL TEMPORARY TABLE GLOBAL_X
(COLUMN_X INTEGER NOT NULL)

COLUMN_X skal selvfølgelig have samme kolonne-type som i TABLE_X. Hvis du synes, at andre skal kunne benytte tabel GLOBAL_X, så skal du huske at lave en GRANT ALL ON GLOBAL_X TO ANDRE. Her må du selv bestemme, hvem ANDRE er, men PUBLIC er altid godt. Nu kan vi lave SQL-kaldet fra før om til to SQL-kald, hvor det sidste SQL-kald giver samme resultat, som SQL-kaldet fra før:

INSERT INTO GLOBAL_X (COLUMN_X)
SELECT COLUMN_X FROM TABLE_X
WHERE COLUMN_Y = 'DELTA'
;
SELECT *
FROM TABLE_A TA, TABLE_B TB
WHERE TA.COLUMN_A IN
( SELECT COLUMN_X FROM GLOBAL_X )
AND TB.COLUMN_B IN
( SELECT COLUMN_X FROM GLOBAL_X )
AND TA.JOIN_COLUMN = TB.JOIN_COLUMN

Hele dette trick er yderst anvendeligt i SPUFI, især hvis man hele tiden ændrer 'DELTA' til andre værdier. Og hvis GLOBAL_X indeholder en lille procentdel af TABLE_X, så vil du også opleve, at køretiden for din SPUFI bliver mindre.

Jeg har selv benyttet dette trick til at lave noget rekursivt-agtigt SQL, hvor jeg har brug for den samme subselect for hver rekursion. Det hele er bagt sammen i en masse UNION's, som samler resultatet af hver rekursion til et samlet resultat. Beskrivelsen af SQL-kaldet CREATE GLOBAL TEMPORARY TABLE i SQL reference kan i øvrigt med fordel læses.

Forrige danske tip        Last tip in english        Tip oversigten