MainframeSupports
tip uge 7/2003:

Jeg har en gang i et af mine engelske tip kort berørt en anvendelse af EXISTS i SQL-kald. Nu kan EXISTS benyttes til mange forskellige formål, men een ting er givet: EXISTS kan ikke returnere nogen værdier, så hvad skal man egentlig med en SELECT-liste. I det engelske tip skriver jeg SELECT 0 FROM, men hvorfor gør jeg egentlig det?

Lige fra fødslen af DB2 har mange af os fået at vide, at man ikke må bruge SELECT * FROM i sine programmer. Det er helt sikkert også en god ide af grunde, jeg ikke vil berøre her. Men gør det egentlig nogen forskel i den SELECT, der skal undersøge eksistensen af en række i en EXISTS? På et tidspunkt for laaang tid siden undersøgte jeg sagen (gad vide, hvilken version af DB2, det var på?) og fandt ud af, at det gjorde en forskel om jeg skrev SELECT * eller SELECT 0.

Ideen med at skrive SELECT 0 er, at så skal EXISTS SELECT kaldet kun returnere en konstant, som i øvrigt straks kan kastes i jordspyddet. Og forskellen på de to kald så jeg dengang tydeligst, hvis WHERE delen kun refererede til kolonner i samme index. Med SELECT 0 fik jeg INDEX ONLY access, mens SELECT * gav access af data-delen og det var jo total spild af tid. Derfor indførte jeg SELECT 0.

Nogen gange falder man i snak med andre lidelsesfæller og diskuterer optimizerens uransagelige veje. Jeg fik så at vide, at nu om dage gav SELECT * i en EXISTS INDEX ONLY access, som absolut er det mest fornuftige. Om det var en IBM'er eller en mere uvildig person, der sagde det, kan jeg ikke huske, men siden har jeg brugt SELECT 0 og SELECT * lidt i flæng. Så her for nylig opdagede jeg til min gru, at gamle tiders unoder er dukket op igen. Eller også har de aldrig været forsvundet.

Jeg kan kun opfordre til at benytte SELECT 0, for så er der ingen risiko for utilsigtede ekstra opslag i data-delen. Nu er der jo det ved optimizeren, at dens veje netop er uransagelige, så derfor kan det jo godt være, at den nogen gange giver INDEX ONLY med SELECT * og andre gange det modsatte. Derfor kan det godt være, at du synes, at mine oplevelser er det rene sludder, men SELECT 0 er simpelthen det sikreste. Husk at tjek dine statiske bindede programmer, der kan ligge mange små besparelser gemt. Her er problemet bare, at man ikke alene ud fra PLAN_TABLE kan se, om det er en EXISTS, man har med at gøre, så det kan være en større opgave at finde disse små syndere.

Forrige danske tip        Last tip in english        Tip oversigten