Viewing metrics monitor elements from XML documents as rows in a table

One way to view metrics-related information contained in an XML document returned from an event monitor is to convert it into a format where each monitor element appears in a row by itself. This format is useful if you want to view the information in a text-based format, but do not know specifically which monitor elements you want to examine.

About this task

To view metrics information in row-based format from the XML documents returned by various monitoring interfaces, use the MON_FORMAT_XML_* _BY ROW table functions. These functions were introduced in DB2® Version 9.7 Fix Pack 1.

Procedure

The example shown in this task uses the MON_FORMAT_XML_TIMES_BY_ROW table function to view component times for a statement as tracked by the package cache event monitor. It assumes that a package cache event monitor called PKGCACHEEVENTS has been created and activated. The package cache event monitor writes its output to an unformatted event (UE) table. Before it can be used, the data in the UE table must be converted to either relational tables using the EVMON_FORMAT_UE_TO_TABLES stored procedure, or to XML using the EVMON_FORMAT_UE_TO_XML table function. This task shows the first of these two approaches.

  1. First, convert the unformatted event (UE) table that the package cache event monitor writes to into relational tables using the EVMON_FORMAT_UE_TO_TABLES procedure
    call EVMON_FORMAT_UE_TO_TABLES ('PkgCache',NULL,NULL,NULL,NULL,NULL,
         NULL,0,'SELECT * FROM PKGCACHEEVENTS')
    This procedure creates two tables:
    • One is called PKGCACHE_EVENT, which contains a column called METRICS. This column, in turn, contains XML documents with metrics monitor elements.
    • The other is called PKGCACHE_METRICS.
      Note: You could view the metrics directly from the columns in PKGCACHE_METRICS, rather than extract metrics from the METRICS column of the PKGCACHE_EVENT table. However, when you examine PKGCACHE_METRICS, the metrics appear in columns, rather than rows; it is not as easy to get a ranking of, say, the metrics with the highest values.
  2. Query the two tables produced in the preceding step to determine which statement is the most expensive in terms of execution times:
    SELECT EVENTS.EXECUTABLE_ID, 
           SUM(METRICS.STMT_EXEC_TIME) AS TOTAL_STMT_EXEC_TIME
    FROM   PKGCACHE_EVENT AS EVENTS, 
           PKGCACHE_METRICS AS METRICS 
    WHERE  EVENTS.XMLID = METRICS.XMLID 
    GROUP  BY EVENTS.EXECUTABLE_ID
    ORDER  BY TOTAL_STMT_EXEC_TIME DESC
    FETCH  FIRST 5 ROWS ONLY
    In the preceding query, the two tables produced in step 1 are joined so that the statement IDs from the PKGCACHE_EVENT table can be associated with their execution times in the PKGCACHE_METRICS table:
    EXECUTABLE_ID                                                       TOTAL_STMT_EXEC_TIME
    ------------------------------------------------------------------- --------------------
    x'01000000000000001A0300000000000000000000020020091215115933859000'                  250
    x'0100000000000000150300000000000000000000020020091215115850328000'                  191
    x'0100000000000000210200000000000000000000020020091215115818343001'                  129
    x'0100000000000000C40200000000000000000000020020091215115838578000'                   41
    x'0100000000000000B00200000000000000000000020020091215115838203000'                   38
    
      5 record(s) selected.
    The first item in the results represents the statement with the largest overall execution time.
  3. Optional: If you like, you can display the text for the statement using the following SQL:
    SELECT SUBSTR(STMT_TEXT,1,60) AS STMT_TEXT 
    FROM PKGCACHE_EVENT 
    WHERE EXECUTABLE_ID = x'01000000000000001A0300000000000000000000020020091215115933859000'
    Results:
    STMT_TEXT
    ------------------------------------------------------------
    DROP XSROBJECT MYSCHEMA.EVMON_PKGCACHE_SCHEMA_SQL09070
    
      1 record(s) selected.
  4. Use the MON_FORMAT_XML_TIMES_BY_ROW table function to view a listing of the time-spent monitor elements for the statement you identified in step 2:
    SELECT SUBSTR(XMLMETRICS.METRIC_NAME,1,30) AS METRIC_NAME,
           XMLMETRICS.TOTAL_TIME_VALUE, 
           SUBSTR(XMLMETRICS.PARENT_METRIC_NAME,1,30) AS PARENT_METRIC_NAME
    FROM PKGCACHE_EVENT AS EVENTS, 
         TABLE(MON_FORMAT_XML_TIMES_BY_ROW(EVENTS.METRICS)) AS XMLMETRICS 
    WHERE EVENTS.EXECUTABLE_ID=
    x'01000000000000001A0300000000000000000000020020091215115933859000' 
     AND PARENT_METRIC_NAME='STMT_EXEC_TIME'
    ORDER BY XMLMETRICS.TOTAL_TIME_VALUE DESC
    
    Notes:
    • Remember that time-spent monitor elements are organized into hierarchies. To eliminate double-counting, only those metrics that roll-up to stmt_exec_time are included in the results. Otherwise, stmt_exec_time itself would be included in the results, which includes several individual component times.
    • PARENT_METRIC_NAME, one of the columns returned by MON_FORMAT_XML_TIMES_BY_ROW is included for illustrative purposes.
    When run, the following results are returned by this query:
    METRIC_NAME                    TOTAL_TIME_VALUE     PARENT_METRIC_NAME
    ------------------------------ -------------------- ------------------------------
    TOTAL_ACT_WAIT_TIME                             234 STMT_EXEC_TIME
    TOTAL_SECTION_PROC_TIME                          15 STMT_EXEC_TIME
    Here, you can see that the total processing time adds up to 249 ms. Compare this time to the total time of 250 shown in step 2; the extra millisecond is accounted for by other times (for example, waits) not included in stmt_exec_time.

Results

In the results from the preceding example, you can see the arrangement of the metrics: they appear in row-oriented format, one metric per row. The advantage of using this approach is that you do not need to know ahead of time which metrics or monitor elements you want to see. If you want to see which of the time-spent metrics have the five highest values, or which metrics fall within a specific range of values, you can easily create a query to return the results you are interested in. By contrast, if you use the XMLTABLE function to display the monitor elements as columns, you need to specify which monitor elements to display (or display them all).

Example

Viewing the contents of the DETAILS column produced by a MON_GET_*_DETAILS table function

You can also use the MON_FORMAT_XML_*_BY_ROW functions to view the contents of the DETAILS column returned by any of the MON_GET_*_DETAILS functions. For example, MON_GET_CONNECTION_DETAILS returns a DETAILS column that contains an XML document with metrics that pertain to a database connection.

For example, to view the non-zero component times for each connection across all members, you could use the following query:
SELECT CONDETAILS.APPLICATION_HANDLE, 
       SUBSTR(XMLMETRICS.METRIC_NAME,1,30) AS METRIC_NAME, 
       SUM(XMLMETRICS.TOTAL_TIME_VALUE) AS TOTAL_TIME_VALUE, 
       SUBSTR(XMLMETRICS.PARENT_METRIC_NAME,1,30) AS PARENT_METRIC_NAME
FROM TABLE(MON_GET_CONNECTION_DETAILS(NULL,-1)) AS CONDETAILS, 
     TABLE(MON_FORMAT_XML_COMPONENT_TIMES_BY_ROW(CONDETAILS.DETAILS))AS XMLMETRICS 
WHERE TOTAL_TIME_VALUE > 0 AND XMLMETRICS.PARENT_METRIC_NAME='TOTAL_RQST_TIME'
GROUP BY CONDETAILS.APPLICATION_HANDLE, 
         XMLMETRICS.PARENT_METRIC_NAME, 
         XMLMETRICS.METRIC_NAME
ORDER BY CONDETAILS.APPLICATION_HANDLE ASC, TOTAL_TIME_VALUE DESC
Notes:
  • To eliminate double-counting, only those metrics that roll-up to total_rqst_time are included in the results (WHERE .... XMLMETRICS.PARENT_METRIC_NAME='TOTAL_RQST_TIME'). Otherwise, total_rqst_time itself would be included in the results, which includes several individual component times.
  • PARENT_METRIC_NAME, one of the columns returned by MON_FORMAT_XML_COMPONENT_TIMES_BY_ROW is included for illustrative purposes.
The preceding query returns the following results:
APPLICATION_HANDLE   METRIC_NAME                    TOTAL_TIME_VALUE     PARENT_METRIC_NAME
-------------------- ------------------------------ -------------------- ------------------------------
                  52 TOTAL_SECTION_TIME                             3936 TOTAL_RQST_TIME
                  52 TOTAL_COMPILE_TIME                              482 TOTAL_RQST_TIME
                  52 TOTAL_COMMIT_TIME                                15 TOTAL_RQST_TIME
                  52 TOTAL_ROLLBACK_TIME                               1 TOTAL_RQST_TIME
                 496 TOTAL_COMPILE_TIME                              251 TOTAL_RQST_TIME
                 496 TOTAL_SECTION_TIME                               46 TOTAL_RQST_TIME
                 496 TOTAL_IMPLICIT_COMPILE_TIME                       5 TOTAL_RQST_TIME

  7 record(s) selected.
As this example shows, only metrics that comprise total_rqst_time are included. Had the WHERE .... XMLMETRICS.PARENT_METRIC_NAME='TOTAL_RQST_TIME' clause not been included in the query, the results would look like those that follow:
APPLICATION_HANDLE   METRIC_NAME                    TOTAL_TIME_VALUE     PARENT_METRIC_NAME
-------------------- ------------------------------ -------------------- ------------------------------
                  52 TOTAL_RQST_TIME                                4603 -
                  52 TOTAL_SECTION_TIME                             3942 TOTAL_RQST_TIME
                  52 TOTAL_COMPILE_TIME                              537 TOTAL_RQST_TIME
                  52 TOTAL_SECTION_SORT_TIME                         299 TOTAL_SECTION_TIME
                  52 TOTAL_COMMIT_TIME                                15 TOTAL_RQST_TIME
                  52 TOTAL_ROLLBACK_TIME                               1 TOTAL_RQST_TIME
                 496 TOTAL_RQST_TIME                                 341 -
                 496 TOTAL_COMPILE_TIME                              251 TOTAL_RQST_TIME
                 496 TOTAL_SECTION_TIME                               46 TOTAL_RQST_TIME
                 496 TOTAL_IMPLICIT_COMPILE_TIME                       5 TOTAL_RQST_TIME
                 496 TOTAL_SECTION_SORT_TIME                           2 TOTAL_SECTION_TIME

  11 record(s) selected.
In this case, the values for total_rqst_time for each connection are included in the results, which includes the values for all other elements for which it is the parent. Similarly, the values for items in italics roll up to the total_section_time. Had they not been excluded in the WHERE clause, they would have been triple-counted in the results, as total_section_time itself rolls up to total_rqst_time.