| 
  
   
     
   
   | 
  
   
     
   
   | 
 
   
     
   
   | 
  ||
Met enige regelmaat brengt ABIS enkele artikelen over DB2 onder de titel Exploring DB2 .
In de Exploring DB2 van januari 2010 nodigde Peter Vanroose ons - de lezers - uit om een query in te sturen voor het presenteren van informatie uit de extended explain tabellen. Deze uitdaging heb ik natuurlijk graag aangenomen.
Dit document bevat de volgende onderdelen:
Voor de broodnodige variatie wilde ik een query maken met een Common Table Expression en ten minste één gepartitioneerde tabel. Een catalog query was daardoor minder geschikt. Dus heb ik een query gebouwd op de IVP database, want deze bevat een gepartitioneerde tabel. Bovendien hebben de meeste installaties de IVP database geïnstalleerd en hopelijk kan iedereen daardoor uit de voeten met onderstaande query.
Dat dit geen bijzonder efficiënte query is, behoeft geen
 betoog.
 Deze keer gaat het immers alleen om de explain data, niet om de
 performance van de query. Optimalisatie van deze query valt dan ook
 buiten de scope van dit artikel, evenals het aanmaken van de extended
 explain tabellen.
 (Die staan overigens beschreven in de
 Performance Monitoring and Tuning Guide
 en worden aangemaakt door OSC. U kunt ook member DSNTIJOS uit de
 SDSNSAMP gebruiken.)
--
   with     managers
           (mgrno,
            mgrname
            )
   as      (select   distinct
                     mgr.empno
                   , strip(coalesce(firstnme, '')) CONCAT
                     ' ' CONCAT
                     strip(coalesce(lastname, '???')) as mgrname
            from     DSN8810.DEPT dept
            join     DSN8810.EMP  mgr
                 on  mgr.empno = dept.mgrno
            )
   select   mgr.mgrname
          , dept.deptname
          , emp.lastname
          , emp.firstnme
   from     DSN8810.EMP emp
   left outer join
            DSN8810.DEPT dept
        on  dept.deptno = emp.workdept
   left outer join
            managers mgr
        on  mgr.mgrno = dept.mgrno
   where    emp.empno between '000000' and '150000'
        and emp.workdept between 'A' and 'EEE'
   order by case when dept.deptno IS NULL
                 then '*No dept'
                 when mgr.mgrno IS NULL
                 then '*No mgr'
                 else mgr.mgrname
            end,
            emp.empno
  ;
---------+---------+---------+---------+---------+---------+---------+---------+---------+--------- MGRNAME DEPTNAME LASTNAME FIRSTNME ---------+---------+---------+---------+---------+---------+---------+---------+---------+--------- CHRISTINE HAAS SPIFFY COMPUTER SERVICE DIV. HAAS CHRISTINE CHRISTINE HAAS SPIFFY COMPUTER SERVICE DIV. LUCCHESI VINCENZO CHRISTINE HAAS SPIFFY COMPUTER SERVICE DIV. O'CONNELL SEAN EVA PULASKI ADMINISTRATION SYSTEMS PULASKI EVA EVA PULASKI ADMINISTRATION SYSTEMS JEFFERSON JAMES EVA PULASKI ADMINISTRATION SYSTEMS MARINO SALVATORE EVA PULASKI ADMINISTRATION SYSTEMS SMITH DANIEL EVA PULASKI ADMINISTRATION SYSTEMS JOHNSON SYBIL EVA PULASKI ADMINISTRATION SYSTEMS PEREZ MARIA IRVING STERN MANUFACTURING SYSTEMS STERN IRVING IRVING STERN MANUFACTURING SYSTEMS ADAMSON BRUCE IRVING STERN MANUFACTURING SYSTEMS PIANKA ELIZABETH IRVING STERN MANUFACTURING SYSTEMS YOSHIMURA MASATOSHI IRVING STERN MANUFACTURING SYSTEMS SCOUTTEN MARILYN IRVING STERN MANUFACTURING SYSTEMS WALKER JAMES IRVING STERN MANUFACTURING SYSTEMS BROWN DAVID IRVING STERN MANUFACTURING SYSTEMS JONES WILLIAM IRVING STERN MANUFACTURING SYSTEMS LUTZ JENNIFER MICHAEL THOMPSON PLANNING THOMPSON MICHAEL SALLY KWAN INFORMATION CENTER KWAN SALLY SALLY KWAN INFORMATION CENTER QUINTANA DOLORES SALLY KWAN INFORMATION CENTER NICHOLLS HEATHER DSNE610I NUMBER OF ROWS DISPLAYED IS 22 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 100
Na uitvoering van
EXPLAIN ALL SET QUERYNO=114 FOR
met bovenstaande query hebben we de diverse explain tabellen voorzien van data.
Een basis-query op alleen de PLAN_TABLE levert het inzicht op, dat er 7 stappen (tabelregels) zijn voor het uitvoeren van deze query. Uit de DSN_SORT_TABLE leren we dat er 4 sort-stappen zijn: twee voor de order-by clause, 1 voor de distinct clause in de Common Table Expression, en 1 voor het uitvoeren van de join met de resultaat-set van de CTE.
Als eerste stap wilde ik mijn standaard-query voor PLAN_TABLE uitbreiden met gegevens voor een eventuele page-range scan. Dat maakt immers een tablespace scan (accesstype=R) iets minder bezwaarlijk... Hiertoe dienen we de betreffende info uit de tabel DSN_PGRANGE_TABLE te gebruiken. Ik heb er voor gekozen om het aantal deelnemende partities toe te voegen aan de access kolom.
Bij onderstaande query en resultaten vallen de volgende zaken op:
De query en bijbehorende resultaten zien er als volgt uit:
--
-- Query on PLAN_TABLE with Page-Range info
--
   SELECT   SUBSTR(STRIP(CHAR(PLAN.QUERYNO)), 1, 5) AS QUERY
          , CASE PLAN.PARENT_QBLOCKNO
                 WHEN 0 THEN ' '
                        ELSE
                        SUBSTR(STRIP(CHAR(PLAN.PARENT_QBLOCKNO)), 1, 4)
            END AS PBLK
          , SUBSTR(STRIP(CHAR(PLAN.QBLOCKNO)), 1, 4) AS QBLK
          , SUBSTR(STRIP(CHAR(PLAN.PLANNO)), 1, 4) AS PLNO
          , CASE PLAN.MIXOPSEQ
                 WHEN 0 THEN ' '
                        ELSE SUBSTR(STRIP(CHAR(PLAN.MIXOPSEQ)), 1, 4)
            END AS OPSQ
          , PLAN.QBLOCK_TYPE AS TYPE
          , CASE PLAN.JOIN_TYPE
                 WHEN 'F' THEN 'Full'
                 WHEN 'P' THEN 'Pair'
                 WHEN 'S' THEN 'Star'
                 WHEN 'L' THEN CASE PLAN.METHOD
                                    WHEN 1 THEN 'L/R'
                                    WHEN 2 THEN 'L/R'
                                    WHEN 4 THEN 'L/R'
                                           ELSE '?'
                                    END
                 WHEN ' ' THEN CASE PLAN.METHOD
                                    WHEN 1 THEN 'Innr'
                                    WHEN 2 THEN 'Innr'
                                    WHEN 4 THEN 'Innr'
                                           ELSE ' '
                                    END
                          ELSE '*ERR*'
            END AS JOIN
          , CASE PLAN.METHOD
                 WHEN 0 THEN 'First'
                 WHEN 1 THEN 'NLjoin'
                 WHEN 2 THEN 'MSjoin'
                 WHEN 3 THEN 'Sort'
                 WHEN 4 THEN 'Hybrid'
                        ELSE 'UNKNWN'
            END AS METHOD
          , CASE PLAN.TABLE_TYPE
                 WHEN 'B' THEN 'Buffer'
                 WHEN 'C' THEN 'CTE'
                 WHEN 'F' THEN 'TabFun'
                 WHEN 'M' THEN 'MQT'
                 WHEN 'Q' THEN 'Temp'
                 WHEN 'R' THEN 'Recurs'
                 WHEN 'T' THEN 'Table'
                 WHEN 'W' THEN 'Work'
                          ELSE ' '
            END AS TYPE
          , SUBSTR(PLAN.CREATOR, 1, 8) AS CREATOR
          , SUBSTR(PLAN.TNAME, 1, 18) AS TABLE
          , SUBSTR(PLAN.ACCESSNAME, 1, 8) AS NDXNAME
          , CASE PLAN.PRIMARY_ACCESSTYPE
                 WHEN 'D' THEN 'D/'
                 WHEN 'T' THEN 'T/'
                          ELSE ''
            END CONCAT
            STRIP(PLAN.ACCESSTYPE) CONCAT
            CASE WHEN PLAN.PAGE_RANGE = 'Y'
                 THEN '(' CONCAT
                      STRIP(SUBSTR(STRIP(CHAR(RANGE.NUMPARTS)), 1, 4))
                      CONCAT ')'
                 ELSE ''
            END AS ACCESS
          , CASE PLAN.PREFETCH
                 WHEN 'S' THEN 'SEQ'
                 WHEN 'L' THEN 'LST'
                 WHEN 'D' THEN 'DYN'
                          ELSE ' '
            END AS PREF
          , CASE PLAN.INDEXONLY
                 WHEN 'Y' THEN 'XO'
                          ELSE ' '
            END AS XO
          , CASE PLAN.MATCHCOLS
                 WHEN 0 THEN ''
                        ELSE SUBSTR(STRIP(CHAR(PLAN.MATCHCOLS)), 1, 2)
            END AS MC
          , CASE PLAN.SORTC_GROUPBY
                 WHEN 'Y' THEN 'G'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTC_JOIN
                 WHEN 'Y' THEN 'J'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTC_ORDERBY
                 WHEN 'Y' THEN 'O'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTC_UNIQ
                 WHEN 'Y' THEN 'U'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTN_GROUPBY
                 WHEN 'Y' THEN 'G'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTN_JOIN
                 WHEN 'Y' THEN 'J'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTN_ORDERBY
                 WHEN 'Y' THEN 'O'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTN_UNIQ
                 WHEN 'Y' THEN 'U'
                          ELSE ' '
            END AS GJOUGJOU
          , CASE PLAN.PARALLELISM_MODE
                 WHEN 'I' THEN 'I/O'
                 WHEN 'C' THEN 'CPU'
                 WHEN 'X' THEN 'SYS'
                          ELSE ' '
            END AS PAR
          , CASE PLAN.CTEREF
                 WHEN 0 THEN ' '
                 ELSE STRIP(CHAR(PLAN.CTEREF))
            END AS CTEREF
   FROM     PLAN_TABLE PLAN
   LEFT OUTER JOIN
            DSN_PGRANGE_TABLE RANGE
        ON  RANGE.QUERYNO  = PLAN.QUERYNO
        AND RANGE.QBLOCKNO = PLAN.QBLOCKNO
        AND RANGE.TABNO    = PLAN.TABNO
   WHERE    PLAN.QUERYNO = 114
   ORDER BY PLAN.QUERYNO
          , PLAN.PARENT_QBLOCKNO DESC
          , PLAN.QBLOCKNO
          , PLAN.PLANNO
          , PLAN.MIXOPSEQ
  ;
---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+--------- QUERY PBLK QBLK PLNO OPSQ TYPE JOIN METHOD TYPE CREATOR TABLE NDXNAME ACCESS PREF XO MC GJOUGJOU PAR CTEREF ---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+--------- 114 1 3 1 TABLEX First Table DSN8810 DEPT XDEPT2 I XO 114 1 3 2 TABLEX Innr NLjoin Table DSN8810 EMP XEMP1 I 1 114 1 3 3 TABLEX Sort U 114 1 1 SELECT First Table DSN8810 EMP XEMP2 I(2) LST 1 114 1 2 SELECT L/R NLjoin Table DSN8810 DEPT XDEPT1 I 1 114 1 3 SELECT L/R NLjoin Work TU00001 MANAGERS T/R J 114 1 4 SELECT Sort O DSNE610I NUMBER OF ROWS DISPLAYED IS 7 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 100
Vervolgens wilde ik zien, of ik ook de informatie uit DSN_SORT_TABLE in deze query kon opnemen om zo een beter totaal-beeld van de query te verkrijgen. Complicatie hierbij is, dat dit aanvullende rijen uit een andere tabel betreft, en dat er dus een UNION ALL moet worden toegepast. Op zich geen punt, maar het heeft wel enkele consequenties:
Allereerst dient de ORDER BY clausule aangepast te worden. Deze kan niet langer met kolom-namen werken, maar moet nu worden geformuleerd met gebruikmaking van kolom-nummers. Dat maakt de query minder leesbaar en begrijpelijk, maar het is niet anders.
Tevens ontstaat nu de situatie dat beide sub-queries een WHERE-clausule bevatten waarin de juiste query moet worden geselecteerd voor het ophalen van de explain data. Ik houd daar niet van; enerzijds omdat het redundant is, en anderzijds omdat het te vaak gebeurt dat de where clausules uit de pas gaan lopen, waardoor het eindresultaat niet meer bruikbaar is. Daarom heb ik de CTE QUERIES toegevoegd om het nummer (of de nummers) van de te explainen query/queries te definiëren.
Verder bleek ik nog twee extra CTEs nodig te hebben om de te
 sorteren tabel-nummers en de bijbehorende tabel-namen te vinden.
 Om de resultaten van deze CTEs in omvang te beperken, heb ik opnieuw
 gebruik gemaakt van de CTE QUERIES die de relevante query-nummers
 bevat. Zodoende vervangt de CTE QUERIES nu in totaal 4 WHERE
 clausules.
Aldus heb ik drie CTEs aan mijn query toegevoegd om mijn query
 verder mee uit te bouwen. Dit hield echter een risico in:
 bij gebruik van drie of meer CTEs kan een CONCAT functie in de
 resultaat-set resulteren in kolom-waarden die een extra voorloop-byte
 krijgen met waarde X'00', wat erg storend kan zijn.
 In deze query komt dat gelukkig niet voor. Dat komt omdat niet
 voldaan is aan de "eis" voor het optreden van dit probleem
 dat er tussen de CTEs een specifieke relatie moet bestaan.
Nadat ik dat had geverifieerd kon ik de query daadwerkelijk verder uitwerken. Het eerste deel van de query bleef vrijwel ongewijzigd. Eigenlijk hoefde alleen de Where-clausule aangepast te worden. De selectie op query-nummer moest worden vervangen door een inner join met de relevante query-nummers (CTE queries). Maar omdat de SORT-gegevens nu uit een andere tabel gehaald gaan worden, kunnen de rijen met METHOD=3 worden overgeslagen.
Voor het toevoegen van de sorteer-gegevens is een tweede query aan de eerste toegevoegd. Deze levert natuurlijk een resultaat-set met dezelfde kolommen, maar haalt haar informatie uit DSN_SORT_TABLE in plaats van PLAN_TABLE.
Ook bij deze query zijn enkele kanttekeningen te plaatsen:
Deze query en bijbehorende resultaten zien er als volgt uit:
--
-- Query on PLAN_TABLE with Page-Range info
--                      and sorting info
--
   WITH     QUERIES
           (QUERYNO)
   AS      (SELECT   114
            FROM     SYSIBM.SYSDUMMY1
            )
          , SORTKEYS
   AS      (SELECT DISTINCT
                     SKEY.QUERYNO
                   , SKEY.QBLOCKNO
                   , SKEY.PLANNO
                   , SKEY.SORTNO
                   , SKEY.TABNO
            FROM     DSN_SORTKEY_TABLE SKEY
            JOIN     QUERIES QRYS
                 ON  QRYS.QUERYNO = SKEY.QUERYNO
            WHERE    SKEY.TABNO <> 0
            )
          , TABLES
   AS      (SELECT DISTINCT
                     PLAN.QUERYNO
                   , PLAN.TABNO
                   , PLAN.TABLE_TYPE
                   , PLAN.CREATOR
                   , PLAN.TNAME
            FROM     PLAN_TABLE PLAN
            JOIN     QUERIES QRYS
                 ON  QRYS.QUERYNO = PLAN.QUERYNO
            WHERE    PLAN.TABNO <> 0
            )
   SELECT   SUBSTR(STRIP(CHAR(PLAN.QUERYNO)), 1, 5) AS QUERY
          , CASE PLAN.PARENT_QBLOCKNO
                 WHEN 0 THEN ' '
                        ELSE
                        SUBSTR(STRIP(CHAR(PLAN.PARENT_QBLOCKNO)), 1, 4)
            END AS PBLK
          , SUBSTR(STRIP(CHAR(PLAN.QBLOCKNO)), 1, 4) AS QBLK
          , SUBSTR(STRIP(CHAR(PLAN.PLANNO)), 1, 4) AS PLNO
          , CASE PLAN.MIXOPSEQ
                 WHEN 0 THEN ' '
                        ELSE SUBSTR(STRIP(CHAR(PLAN.MIXOPSEQ)), 1, 4)
            END AS OPSQ
          , PLAN.QBLOCK_TYPE AS TYPE
          , CASE PLAN.JOIN_TYPE
                 WHEN 'F' THEN 'Full'
                 WHEN 'P' THEN 'Pair'
                 WHEN 'S' THEN 'Star'
                 WHEN 'L' THEN CASE PLAN.METHOD
                                    WHEN 1 THEN 'L/R'
                                    WHEN 2 THEN 'L/R'
                                    WHEN 4 THEN 'L/R'
                                           ELSE '?'
                                    END
                 WHEN ' ' THEN CASE PLAN.METHOD
                                    WHEN 1 THEN 'Innr'
                                    WHEN 2 THEN 'Innr'
                                    WHEN 4 THEN 'Innr'
                                           ELSE ' '
                                    END
                          ELSE '*ERR*'
            END AS JOIN
          , CASE PLAN.METHOD
                 WHEN 0 THEN 'First'
                 WHEN 1 THEN 'NLjoin'
                 WHEN 2 THEN 'MSjoin'
                 WHEN 3 THEN 'Sort'
                 WHEN 4 THEN 'Hybrid'
                        ELSE 'UNKNWN'
            END AS METHOD
          , CASE PLAN.TABLE_TYPE
                 WHEN 'B' THEN 'Buffer'
                 WHEN 'C' THEN 'CTE'
                 WHEN 'F' THEN 'TabFun'
                 WHEN 'M' THEN 'MQT'
                 WHEN 'Q' THEN 'Temp'
                 WHEN 'R' THEN 'Recurs'
                 WHEN 'T' THEN 'Table'
                 WHEN 'W' THEN 'Work'
                          ELSE ' '
            END AS TYPE
          , SUBSTR(PLAN.CREATOR, 1, 8) AS CREATOR
          , SUBSTR(PLAN.TNAME, 1, 18) AS TABLE
          , SUBSTR(PLAN.ACCESSNAME, 1, 8) AS NDXNAME
          , CASE PLAN.PRIMARY_ACCESSTYPE
                 WHEN 'D' THEN 'D/'
                 WHEN 'T' THEN 'T/'
                          ELSE ''
            END CONCAT
            STRIP(PLAN.ACCESSTYPE) CONCAT
            CASE WHEN PLAN.PAGE_RANGE = 'Y'
                 THEN '(' CONCAT
                      STRIP(SUBSTR(STRIP(CHAR(RANGE.NUMPARTS)), 1, 4))
                      CONCAT ')'
                 ELSE ''
            END AS ACCESS
          , CASE PLAN.PREFETCH
                 WHEN 'S' THEN 'SEQ'
                 WHEN 'L' THEN 'LST'
                 WHEN 'D' THEN 'DYN'
                          ELSE ' '
            END AS PREF
          , CASE PLAN.INDEXONLY
                 WHEN 'Y' THEN 'XO'
                          ELSE ' '
            END AS XO
          , CASE PLAN.MATCHCOLS
                 WHEN 0 THEN ''
                        ELSE SUBSTR(STRIP(CHAR(PLAN.MATCHCOLS)), 1, 2)
            END AS MC
          , CASE PLAN.SORTC_GROUPBY
                 WHEN 'Y' THEN 'G'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTC_JOIN
                 WHEN 'Y' THEN 'J'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTC_ORDERBY
                 WHEN 'Y' THEN 'O'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTC_UNIQ
                 WHEN 'Y' THEN 'U'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTN_GROUPBY
                 WHEN 'Y' THEN 'G'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTN_JOIN
                 WHEN 'Y' THEN 'J'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTN_ORDERBY
                 WHEN 'Y' THEN 'O'
                          ELSE ' '
            END CONCAT
            CASE PLAN.SORTN_UNIQ
                 WHEN 'Y' THEN 'U'
                          ELSE ' '
            END AS GJOUGJOU
   FROM     PLAN_TABLE PLAN
   JOIN     QUERIES QRYS
        ON  QRYS.QUERYNO = PLAN.QUERYNO
   LEFT OUTER JOIN
            DSN_PGRANGE_TABLE RANGE
        ON  RANGE.QUERYNO  = PLAN.QUERYNO
        AND RANGE.QBLOCKNO = PLAN.QBLOCKNO
        AND RANGE.TABNO    = PLAN.TABNO
   WHERE    PLAN.METHOD <> 3
  UNION ALL
   SELECT   SUBSTR(STRIP(CHAR(PLAN.QUERYNO)), 1, 5) AS QUERY
          , CASE PLAN.PARENT_QBLOCKNO
                 WHEN 0 THEN ' '
                        ELSE
                        SUBSTR(STRIP(CHAR(PLAN.PARENT_QBLOCKNO)), 1, 4)
            END AS PBLK
          , SUBSTR(STRIP(CHAR(PLAN.QBLOCKNO)), 1, 4) AS QBLK
          , SUBSTR(STRIP(CHAR(PLAN.PLANNO)), 1, 4) AS PLNO
          , CASE WHEN PLAN.MIXOPSEQ <> 0
                 THEN SUBSTR(STRIP(CHAR(PLAN.MIXOPSEQ)), 1, 4)
                 ELSE ''
            END CONCAT
            CASE WHEN SORT.SORTNO > 0
                 THEN SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                             SORT.SORTNO, 1)
                 ELSE ''
            END AS OPSQ
          , PLAN.QBLOCK_TYPE AS TYPE
          , '' AS JOIN
          , 'Sort' AS METHOD
          , CASE TBLS.TABLE_TYPE
                 WHEN 'B' THEN 'Buffer'
                 WHEN 'C' THEN 'CTE'
                 WHEN 'F' THEN 'TabFun'
                 WHEN 'M' THEN 'MQT'
                 WHEN 'Q' THEN 'Temp'
                 WHEN 'R' THEN 'Recurs'
                 WHEN 'T' THEN 'Table'
                 WHEN 'W' THEN 'Work'
                          ELSE ' '
            END AS TYPE
          , SUBSTR(TBLS.CREATOR, 1, 8) AS CREATOR
          , SUBSTR(TBLS.TNAME, 1, 18) AS TABLE
          , SUBSTR(PLAN.ACCESSNAME, 1, 8) AS NDXNAME
          , CASE PLAN.PRIMARY_ACCESSTYPE
                 WHEN 'D' THEN 'D/'
                 WHEN 'T' THEN 'T/'
                          ELSE ''
            END CONCAT
            STRIP(PLAN.ACCESSTYPE)
            AS ACCESS
          , CASE PLAN.PREFETCH
                 WHEN 'S' THEN 'SEQ'
                 WHEN 'L' THEN 'LST'
                 WHEN 'D' THEN 'DYN'
                          ELSE ' '
            END AS PREF
          , CASE PLAN.INDEXONLY
                 WHEN 'Y' THEN 'XO'
                          ELSE ' '
            END AS XO
          , CASE PLAN.MATCHCOLS
                 WHEN 0 THEN ''
                        ELSE SUBSTR(STRIP(CHAR(PLAN.MATCHCOLS)), 1, 2)
            END AS MC
          , SUBSTR(SORT.SORTC, 1, 4) CONCAT
            SUBSTR(SORT.SORTN, 1, 4) AS GJOUGJOU
   FROM     DSN_SORT_TABLE SORT
   JOIN     QUERIES QRYS
        ON  QRYS.QUERYNO = SORT.QUERYNO
   LEFT OUTER JOIN -- Obtain nr of table being sorted
            SORTKEYS SKEY
        ON  SKEY.QUERYNO  = SORT.QUERYNO
        AND SKEY.QBLOCKNO = SORT.QBLOCKNO
        AND SKEY.PLANNO   = SORT.PLANNO
        AND SKEY.SORTNO   = SORT.SORTNO
   LEFT OUTER JOIN -- Obtain name of table being sorted
            TABLES TBLS
        ON  TBLS.QUERYNO = SKEY.QUERYNO
        AND TBLS.TABNO   = SKEY.TABNO
   LEFT OUTER JOIN -- Join back to relevant PLAN_TABLE row
            PLAN_TABLE PLAN
        ON  PLAN.QUERYNO  = SORT.QUERYNO
        AND PLAN.QBLOCKNO = SORT.QBLOCKNO
        AND PLAN.PLANNO   = SORT.PLANNO
        AND(   PLAN.METHOD   = 3
            OR(    PLAN.SORTC_JOIN = 'Y'
               AND SUBSTR(SORT.SORTC, 2, 1) = 'J'
               )
            OR(    PLAN.SORTN_JOIN = 'Y'
               AND SUBSTR(SORT.SORTN, 2, 1) = 'J'
            )  )
   ORDER BY 1, 2 DESC, 3, 4, 5
  ;
---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+------- QUERY PBLK QBLK PLNO OPSQ TYPE JOIN METHOD TYPE CREATOR TABLE NDXNAME ACCESS PREF XO MC GJOUGJOU ---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+------- 114 1 3 1 TABLEX First Table DSN8810 DEPT XDEPT2 I XO 114 1 3 2 TABLEX Innr NLjoin Table DSN8810 EMP XEMP1 I 1 114 1 3 3 A TABLEX Sort Table DSN8810 EMP U 114 1 1 SELECT First Table DSN8810 EMP XEMP2 I(2) LST 1 114 1 2 SELECT L/R NLjoin Table DSN8810 DEPT XDEPT1 I 1 114 1 3 SELECT L/R NLjoin Work TU00001 MANAGERS T/R J 114 1 3 A SELECT Sort Work TU00001 MANAGERS T/R J 114 1 4 A SELECT Sort Table DSN8810 EMP O 114 1 4 B SELECT Sort Table DSN8810 EMP O DSNE610I NUMBER OF ROWS DISPLAYED IS 9 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 100
Opmerkingen? Vragen? Meer informatie? Klik het onderwerp van uw keuze aan, of e-mail ons met uw vragen.
Ten slotte:
 ik had slechts een zeer beperkte set explain gegevens tot mijn
 beschikking. Ik kan dus niet garanderen dat deze queries de explain
 data ook bruikbaar weergeven voor "echte" SQL uit uw
 ontwikkel- of productie-omgevingen.
 Mocht u een defect vinden, dan hoor ik dat natuurlijk graag.
 Ook andere opmerkingen of vragen zijn van harte welkom.
 Naar De query
 Naar Explain met Range informatie
 Naar Explain met Range en Sort informatie.
| 
   Deze site is aangesloten bij WebRing. Bekijkt u gerust de lijst van mainframe-gerelateerde sites.  | 
  
    
   | 
  Dino's zijn niet dood. Ze zijn gezond en wel en leven in computer-centra overal om ons heen. Zij spreken in tongen en doen wonderbare magie met computers. Pas op voor de dino! En voor het geval u zit te wachten op het definitieve einde van deze dino's: onthoud dat dino's de wereld 155 miljoen jaren hebben geregeerd! | 
| 
   Dino's en andere anachronismen [ Aanmelden | Ring Overzicht | Willekeurig | << Vorige | Volgende >> ]  | 
 ||