示例:调查例程的高 CPU 占用率

可以使用例程监视功能来调查例程占用的 CPU 资源量为何高出期望。

方案

在本示例中,数据库管理员 (DBA) 正在调查称为 TEST.PROC1 的关键存储过程的性能。MON_GET_ROUTINE 表函数返回的 TOTAL_ROUTINE_CPU_TIME 监视元素会显示存储过程正在使用的 CPU 资源量高出期望。DBA 先前使用 MON_RTN_EXECLIST 数据库配置参数,将数据库配置为跟踪例程的语句信息。DBA 发出下列查询以计算例程在所有成员上执行的每个语句的 CPU 使用率之和:
WITH TOTAL_STMT_CPU (EXEC_ID, TOTAL_CPU, NUM_ROUTINES, MIN_MEMBER) AS 
  (SELECT 
     EXECUTABLE_ID,
     SUM(TOTAL_CPU_TIME),
     MAX(NUM_ROUTINES),
     MIN(MEMBER) 
   FROM 
     TABLE(MON_GET_ROUTINE_EXEC_LIST('P', 'TEST', NULL, 'PROC1', -2)) AS T 
   GROUP BY 
     EXECUTABLE_ID
  ),
  TOTAL_RTN_CPU (TOTAL_RTN_CPU) AS 
  (SELECT 
     SUM(TOTAL_CPU_TIME) 
   FROM 
     TABLE(MON_GET_ROUTINE('P', 'TEST', NULL, 'PROC1', -2)) AS R
  ) 
SELECT 
  B.EXEC_ID,
  100*B.TOTAL_CPU / A.TOTAL_RTN_CPU AS PERCENT_CPU,
  B.NUM_ROUTINES,
  C.STMT_TEXT 
FROM 
  TOTAL_RTN_CPU AS A,
  TOTAL_STMT_CPU AS B,
  TABLE(MON_GET_PKG_CACHE_STMT(NULL, NULL, NULL, -2)) AS C 
WHERE 
  B.EXEC_ID = C.EXECUTABLE_ID AND 
  B.MIN_MEMBER = C.MEMBER AND 
  A.TOTAL_RTN_CPU<>0 
ORDER BY 
  TOTAL_CPU DESC
结果按相对于例程的总 CPU 使用率的 CPU 占用率 (%) 的排序列出存储过程执行的语句。
EXEC_ID                                                             PERCENT_CPU  NUM_ROUTINES   STMT_TEXT                                   
------------------------------------------------------------------- ------------ -------------- --------------------------------------------
x'0100000000000000560100000000000002000000010020120801142628005514'           10              0 WITH GET_UPDATE_LIST (COL1, COL2STATS) AS AF
x'0100000000000000560100000000000002000000010020120801142628005514'            1              0 insert into T1 values(3,'d','d','d')        
x'0100000000000000560100000000000001000000010020120801142628005514'            0              1 call SYSIBMSUBROUTINE.P1_66613_1157394573() 

  3 record(s) selected.
MON_GET_ROUTINE_EXEC_LIST 表函数报告的每个语句的 CPU 使用率不含任何子语句所占用的 CPU。MON_GET_ROUTINE_EXEC_LIST 生成的报告只显示例程直接调用的语句所占用的 CPU 百分比。DBA 可以继续按下列方式进行调查:
  • 如果直接子语句正在使用大部分 CPU,那么 MON_GET_ROUTINE_EXEC_LIST 报告会标识候选者和 DBA 可以调查该语句。例如,深入研究具有高 CPU 使用率的语句,在此过程中使用 MON_GET_PKG_CACHE_STMT 表函数来列出语句的所有执行的完整指标集:
    SELECT * FROM TABLE(MON_GET_PKG_CACHE_STMT
    (NULL, '<high_cpu_consuming_exec_id>', NULL, -2)) AS T
  • 如果输出显示例程正在直接执行的所有语句都未在使用大量 CPU,那么 DBA 可以检查对每个执行语句列出的 num_routines 监视元素。
    • 如果每个执行语句的 num_routines 为 0(零),那么高 CPU 占用率是由于在例程自身内部进行处理。
    • 如果 num_routines 不为零,那么 DBA 可使用 MON_GET_SECTION_ROUTINE 表函数来确定语句所调用的例程,并调查这些例程是否可能增大 TEST.PROC1 的总体 CPU 占用率。例如:
      SELECT 
         ROUTINESCHEMA, ROUTINEMODULENAME, ROUTINENAME, SPECIFICNAME  
         FROM TABLE(MON_GET_SECTION_ROUTINE('<exec_id>')) AS T 
      返回的结果是:
      ROUTINESCHEMA     ROUTINEMODULENAME  ROUTINENAME                 SPECIFICNAME 
      ----------------- ------------------ --------------------------- -------------
      DRICARD           -                  PROC1                       PROC1        
      SYSIBMSUBROUTINE  -                  PROC1_66613_101877843       -            
      
        2 record(s) selected
      DBA 可以调查这些例程是否造成高 CPU 占用率,但必须牢记例程可能是从 TEST.PROC1 之外的上下文进行调用。这表示 MON_GET_SECTION_ROUTINE 对这些例程返回的指标可能要大于 TEST.PROC1 的指标。