MainframeSupports
tip uge 26/2003:

Et af de emner, der har været og stadig er kilde til megen diskussion, er forskellen på correlated og non-correlated subselects. Jeg har især mange gange set correlated subselects anvendt, hvor en non-correlated subselect er bedre. Det er et af disse eksempler, jeg vil behandle i dette tip.

Følgende SQL-kald eller et der ligner ret meget findes stort set på enhver DB2-installation:

SELECT columna, columnb
FROM tablex x
WHERE keycolumn1 = :key
  AND keycolumn2 =
( SELECT MAX(keycolumn2)
  FROM tablex
  WHERE keycolumn1 = x.keycolumn1
)

Keycolumn1 kunne være et kundenr eller et kontonr. Keycolumn2 kunne så være en form for versionering, måske et timestamp eller et fortløbende nr. Subselect'en i eksemplet er en correlated subselect og derfor udføres den een gang for hver eneste række, der matcher WHERE-clausen i den ydre select. Hvis der eksempelvis er 10 rækker, der matcher værdien i host-variablen :key, ja, så udfører DB2 subselect'en 10 gange, selv om keycolumn1 har samme værdi. DB2 cacher typisk resultatet af en correlated subselect, så i dette tilfælde vil DB2 kun første gang rent faktisk lave opslaget i subselect'en, og de øvrige 9 gange kan den genkende den samme værdi og returnere resultatet. SQL-kaldet kan dog alligevel optimeres betydeligt med følgende lille ændring:

SELECT columna, columnb
FROM tablex x
WHERE keycolumn1 = :key
  AND keycolumn2 =
( SELECT MAX(keycolumn2)
  FROM tablex
  WHERE keycolumn1 = :key
)

Dette SQL-kald giver præcis samme resultat, som det forrige, men nu er det non-correlated. DB2 udfører først subselecten een eneste gang for værdien af :key. Herefter vil DB2 udføre den ydre select een eneste gang med værdien af :key og resultatet af subselect'en. Hvis der kun er een række, der hitter på :key, så er de to SQL-kald præcis lig så effektive, men lige så snart, der er flere end een række, så bliver den non-correlatede udgave den hurtigste. Typisk vil der være et index på keycolumn1, keycolumn2 og derfor vil DB2 benytte MATCHCOLS=2 i det sidste eksempel, mod MATCHCOLS=1 i det første.

Forrige danske tip        Last tip in english        Tip oversigten