MainframeSupports
tip uge 41/2002:

I moderne datamodellering er det meget normalt at medtage versionering eller historik. Det gøres med forskellige metoder og med vekslende held. En ting er dog sikkert, SQL-kaldene mod sådanne datamodeller er ret komplicerede. De involverer typisk brugen af correlated subselects.

Jeg har konstateret, at disse correlated subselects ofte kan optimeres, og det ganske uafhængigt af DB2-versionen, så længe det drejer sig om version 2 eller senere. Lad mig starte med at vise et eksempel, som du kan efterprøve på din egen installation.

SELECT DBNAME, TSNAME, ICDATE, ICTIME
FROM SYSIBM.SYSCOPY Y
WHERE Y.DBNAME = 'DSNDB06'
  AND Y.TIMESTAMP =
( SELECT MAX(S.TIMESTAMP)
  FROM SYSIBM.SYSCOPY S
  WHERE C.DBNAME = S.DBNAME
    AND C.TSNAME = S.TSNAME
    AND C.DSNUM = S.DSNUM
    AND ICTYPE = 'F'
)

Dette SQL-kald vil for hver eneste tablespace i DB2-systemkataloget finde tidspunktet for den seneste full-image copy. Du kan selv justere lidt på det, hvis database DSNDB06 er for kedelig på din installation. Dette SQL-kald er typisk for, hvordan man i mange versionerede datamodeller finder den nyeste version af et eller andet. I netop dette tilfælde er jeg kun interesseret i full-image copies. Nu er det bare således, at der er masser af andre spændende rækker i SYSIBM.SYSCOPY, hvor ICTYPE er alt andet end 'F'. Derfor skal jeg huske at medtage netop betingelsen ICTYPE = 'F' i den ydre select også. Det er sådan set tippet i al sin enkelthed.

Den generelle formulering af tippet er, at betingelser i subselecten, der ikke har noget med selve nøglen at gøre, også skal medtages i selve select'en. Læg mærke til, at hvis betingelsen ICTYPE = 'F' kun medtages i den ydre select, så vil SQL-kaldet med meget stor sandsynlighed ikke returnere det ønskede resultat, med mindre alle rækker i tabellen har 'F' som værdi for ICTYPE. Netop denne oplevelse har fået mange til at flytte betingelsen til subselect'en. Fejlen er bare, at den skal kopieres, ikke flyttes.

Og hvad er egentlig forskellen? Jo, subselecten bliver kun udført for rækker, der opfylder betingelserne i den ydre select. Derfor sparer du DB2 for en ekstra select for hver eneste række, som du kan filtrere fra i den ydre select. Det kan faktisk gøre en stor forskel. Hvis det kun er 20% af rækkerne i SYSIBM.SYSCOPY, der har ICTYPE = 'F', så vil jeg i eksemplet spare 80% af subselect kaldene væk, bare ved at tilføje betingelsen i den ydre select.

Forrige danske tip        Last tip in english        Tip oversigten