例: ルーチンによる 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 はそのステートメントを調査できます。 例えば、MON_GET_PKG_CACHE_STMT 表関数を使用して、CPU 消費量が多いステートメントをドリルダウンし、そのステートメントのすべての実行に関するメトリックの全セットをリストします。
    SELECT * FROM TABLE(MON_GET_PKG_CACHE_STMT
    (NULL, '<high_cpu_consuming_exec_id>', NULL, -2)) AS T
  • 出力に、ルーチンによって直接実行されているステートメントに大量の CPU を使用しているものがないことが示される場合、DBA は実行されたステートメントごとにリストされている num_routines モニター・エレメントを調べることができます。
    • 実行された各ステートメントの num_routines がゼロの場合、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 に関するメトリックよりも大きい可能性があります。