MainframeSupports
tip uge 31/2000:

Næste uges tip udkommer først tirsdag i uge 33.

Jeg har mange gange manipuleret med SQL-kald mod DB2 for at få en bedre accessvej end den DB2 valgte i første omgang. Men det er som nævnt i uge 28 ikke alt, hvad DB2 gør, der kan ses ud af en EXPLAIN. Der står for eksempel i DB2 version 5 manualen Application programming and SQL guide afsnit 6.3.2.2, at betingelser (predicates) på samme stage evalueres i den orden, de optræder i SQL-kaldet.

Det kan med andre ord bedst betale sig at skrive de betingelser, der sorterer flest rækker fra, først. Det har for eksempel den sjove konsekvens, at en WHERE A > 5 AND A < 10 kan give forskellige accessveje afhængig af runstats-informationerne for kolonne A. Hvis LOW2KEY for A er 0 og HIGH2KEY for A er 100, så vil DB2 antage, at 94% af rækkerne er > 5 og dermed vil DB2 ikke finde på at anvende et index, hvor A indgår. At A også skal være mindre end 10 indgår ikke i vurderingen, da kolonne A allerede er blevet evalueret.

Hvis (LOW2KEY, HIGH2KEY) = (-90,10), så vil DB2 antage, at 4% af rækkerne er > 5 og dermed overveje anvendelsen af et index. Og hvad skal man så gøre ved det. For det første skal man overveje om man kan anvende en BETWEEN, hvor der netop tages hensyn til begge værdier. Hvis det ikke umiddelbart er muligt, så skal man ud fra værdierne af LOW2KEY og HIGH2KEY skrive sine WHERE-betingelser i den optimale rækkefølge. I det første eksempel er det altså bedre at skrive WHERE A < 10 AND A > 5, hvor paradoksalt og ulogisk det end må se ud.

Jeg har desuden konstateret, at DB2 har det rigtig dårligt med værdier, der ligger på den forkerte side af LOW2KEY og HIGH2KEY. Lad os antage (LOW2KEY, HIGH2KEY) = (1000,10000) og en WHERE A > 11000 (alternativt A < 0). Selvom A indgår i et index, kan DB2 finde på ikke at anvende index i dette tilfælde, selvom mine beregninger siger mig, at DB2 må antage at 0% af rækkerne vil opfylde betingelsen. Hvis man har sådan et problem kan man snyde ved at skrive WHERE A > 9900 AND A > 11000, hvorefter DB2 er helt vild for at benytte et index, hvor A indgår.

Til sidst er det værd at bemærke, at ovenstående konstateringer kan variere fra DB2 version til DB2 version og endda variere inden for samme version afhængig af PTF-level. Især vil jeg kategorisere den sidst beskrevne problemstilling som en klar fejl i optimizeren. Eksemplerne har jeg lavet som integers, men jeg har faktisk kun prøvet med timestamps, så det er ikke sikkert, at fejlen eksisterer for integers eller for den sags skyld for andre kolonnetyper.

Sidste uges tip        Tip oversigten