MainframeSupports
tip uge 49/2015:

En af de nyeste statements i SQL sproget er MERGE statementet, som er en kombination af INSERT og UPDATE. Jeg har ikke de store erfaringer med at bruge MERGE, men som DBA ser man jo lidt af hvert, herunder de faldgruber, du kan rende ind i med nye statements. Først og fremmest skal man jo lige lære syntaksen at kende. Herefter skal man forstå, hvordan det virker, og til sidst kan man begynde at interessere sig for, hvordan det performer. Og det var performance delen, der fik mig til at skrive dette tip.

Jeg vil ikke gå i detaljer med syntaksen og virkemåden. Den kan du læse om i SQL reference under MERGE. Men der er en vigtig detalje omkring performance, der er udeladt. Og den vil jeg forsøge at beskrive. Forestil dig tabellen MYTABLE med kolonnerne KEYCOL (en integer) og DATACOL (en char/varchar). Der er et index på KEYCOL. Jeg udfører nu følgende MERGE statement:

MERGE INTO MYTABLE
USING (VALUES (1,'The first row')) AS X (A, B) ON (KEYCOL = A)
WHEN MATCHED THEN
  UPDATE SET DATACOL = X.B
WHEN NOT MATCHED THEN
  INSERT (KEYCOL, DATACOL) VALUES (A, B)

Læg mærke til USING delen, hvor der opbygges to variable kaldet A og B. A assignes værdien 1 og B værdien 'The first row'. I value delen kan du selvfølgelig benytte hostvariable i stedet for konstanter. Herefter kan A og B frit benyttes forskellige steder i resten af statementet, dog prefix'et med X hvis der skulle være navnesammenflad med kolonner i tabellen. ON beskriver merge kriteriet. Hvis merge kriteriet er opfyldt udføres UPDATE delen og i modsat fald udføres INSERT delen. I eksemplet betyder det, at hvis der findes en række i MYTABLE, hvor KEYCOL = 1, så overskrives DATACOL for denne række med værdien 'The first row'. I modsat fald insertes en ny række med værdierne i variablene A og B.

I ovenstående tilfælde vil DB2 benytte indexet på KEYCOL til at afgøre om der skal laves insert eller update. Men hvad hvis nu statementet så således ud:

MERGE INTO MYTABLE
USING (VALUES (2,'The second row', 1)) AS X (A, B, C) ON (KEYCOL = A)
WHEN MATCHED THEN
  UPDATE SET DATACOL = X.B, KEYCOL = X.C
WHEN NOT MATCHED THEN
  INSERT (KEYCOL, DATACOL) VALUES (A, B)

Dette merge statement kan benyttes til at opdatere KEYCOL såvel som DATACOL. Det er jo ret fleksibelt, men har den store ulempe, at DB2 ikke vil benytte indexet på KEYCOL. I stedet udfører DB2 en tablespace scan for at finde ud af, om der skal foretages insert eller update. Det simple tip er derfor, at hvis du bruger MERGE skal du lade være med at opdatere kolonner, der indgår i et index, som dit ON kriterie kan drage fordel af. I modsat fald vil MERGE lave tablespace scan.

Forrige danske tip        Last tip in english        Tip oversigten