示例:调查例程的高 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
DBA 可以调查这些例程是否造成高 CPU 占用率,但必须牢记例程可能是从 TEST.PROC1 之外的上下文进行调用。这表示 MON_GET_SECTION_ROUTINE 对这些例程返回的指标可能要大于 TEST.PROC1 的指标。ROUTINESCHEMA ROUTINEMODULENAME ROUTINENAME SPECIFICNAME ----------------- ------------------ --------------------------- ------------- DRICARD - PROC1 PROC1 SYSIBMSUBROUTINE - PROC1_66613_101877843 - 2 record(s) selected