MainframeSupports
tip uge 22/2003:

Når det gælder om at få DB2 optimizeren til at vælge den optimale access vej, så har jeg gennem tiderne benyttet mange forskellige tricks. Enkelte af dem har også udmøntet sig i tip her på min hjemmeside. Nogle af disse tricks er anbefalet af IBM og andre er det aldeles ikke. Et af de anbefalede tricks er anvendelsen af OPTIMIZE FOR n ROWS. Dette trick har jeg hidtil i min ignorance anset for at være ubrugeligt, men jeg er blevet rigtig meget klogere.

OPTIMIZE FOR n ROWS placeres allersidst i dit SQL-kald. Den mest spændende anvendelse af OPTIMIZE FOR n ROWS er at sætte n = 1. Hvis jeg har et SQL-kald, der ter sig anderledes, end jeg vil have det, så starter jeg nu med en OPTIMIZE FOR 1 ROWS og ser på, hvilken access vej det giver. OPTIMIZE FOR 1 ROWS tvinger optimizeren til at vælge den access vej, der hurtigst muligt returnerer den første række til kalderen. Derfor favoriserer OPTIMIZE FOR 1 ROWS nested loop join frem for de andre join metoder. I enkelte tilfælde favoriseres tablespacescan også frem for index access, så nu er du advaret.

Hvis man eksempelvis har et program med en SQL cursor, der returnerer et meget stort antal rækker, så kan der gå ret lang tid inden dit program begynder at fetche igennem rækkerne. Det sker typisk, når DB2 vælger at lave sorteringer, også selv om sorteringsrækkefølgen kan opnås via et index. Sådanne programmer kan være svære at få til at virke fornuftigt med restart, da hver eneste restart først skal danne resultatet, før der kan fetches igennem det. Her vil en OPTIMIZE FOR 1 ROWS sandsynligvis gøre underværker.

Hvis din installation benytter DB2 governor til at stoppe ressourceforbruget af tunge SQL-kald, så kan du også benytte OPTIMIZE FOR 1 ROWS til at forhindre dit SQL-kald i at blive slået ned med SQLCODE -905. Her er tricket, at DB2 governor kun måler på hvert enkelt kald til DB2 og ikke på hele SQL-kaldet. Når du eksempelvis får udført et SQL-kald af SPUFI eller QMF eller lignende, så bliver det opsplittet i en række kald til DB2, først et OPEN CURSOR kald og herefter en fetch for hver række.

Jeg skal til sidst understrege, at OPTIMIZE FOR 1 ROWS i lighed med andre DB2 tiltag ikke er nogen mirakelkur. Det kan sagtens være, at en nested loop join er meget langsommere end en af de andre join metoder samlet set. Og så kan en OPTIMIZE FOR 1 ROWS altså ikke forhindre en sort, hvis din ORDER BY er på kolonner, der ikke er index på, eller er i en anden rækkefølge end i indexet.

Forrige danske tip        Last tip in english        Tip oversigten