モニター表関数とは

イベント・モニターよりも使い勝手いいです。 「MON」で始まる名前を持つルーチンのこと。定期的なアクセスで、パフォーマンスチューニングに役立つ情報を提供してくれる。

MON_GET_DATABASE

SELECT * FROM TABLE(MON_GET_DATABASE(-2))

データベースの概要を見ることができる。毎日見ていると、急激に変化した値で異変を検知できると思うが、個人的にはあんまり見ない。

MON_GET_CONTAINER

SELECT * FROM TABLE(MON_GET_CONTAINER('',-2)) 

表領域のコンテナのパスやコンテナタイプなどを確認できる。

以前は、以下のようなコマンドで確認する必要がありましたが非推奨になりました。

db2 LIST TABLESPACES
db2 LIST TABLESPACE CONTAINERS ${コンテナID} SHOW DETAIL

MON_GET_TABLESPACE

表領域の容量やペンディングのチェックなどに使います。

SELECT * FROM TABLE(MON_GET_TABLESPACE('',-2))

MON_GET_BUFFERPOOL

WITH BPMETRICS AS (
    SELECT bp_name,
           pool_data_l_reads + pool_temp_data_l_reads +
           pool_index_l_reads + pool_temp_index_l_reads +
           pool_xda_l_reads + pool_temp_xda_l_reads as logical_reads,
           pool_data_p_reads + pool_temp_data_p_reads +
           pool_index_p_reads + pool_temp_index_p_reads +
           pool_xda_p_reads + pool_temp_xda_p_reads as physical_reads,
           member
    FROM TABLE(MON_GET_BUFFERPOOL('',-2)) AS METRICS)
   SELECT
    VARCHAR(bp_name,20) AS bp_name,
    logical_reads,
    physical_reads,
    CASE WHEN logical_reads > 0
     THEN DEC((1 - (FLOAT(physical_reads) / FLOAT(logical_reads))) * 100,5,2)
     ELSE NULL
    END AS HIT_RATIO,
    member
   FROM BPMETRICS;

バッファー・プール・ヒット率を参照するぐらいかも。

MON_GET_CONNECTION

SELECT * FROM TABLE(MON_GET_CONNECTION(NULL, -2))

接続している個々の接続情報を提供してくれる。実行した時点の情報なので、アクセス数が多い時間帯に定期的に発行して確認する程度。 WORKLOAD_OCCURRENCE_STATEのUOWEXEC状態が多いとDB2のパフォーマンスが劣化する。

MON_GET_PKG_CACHE_STMT

SELECT * FROM TABLE(MON_GET_PKG_CACHE_STMT(NULL, NULL, NULL, -2)) 

どのSQLで実行時間が長いのかがわかる。CPU時間もわかるので、「どのSQLでCPUが跳ねてるのか?」を調査するのに便利。現在のパッケージ内に保持するSQL情報を返すので、パッケージキャッシュ・ヒット率が悪いアプリケーションなら数時間に一回ぐらいとってたほうがよい。EXECUTABLE_IDでグループ化する必要があるみたいだが、大概、SQL単位で異なるEXECUTABLE_IDなので、いちいちやってない。

以下の項目は要チェック

  • NUM_EXECUTIONS (実行回数)
  • TOTAL_CPU_TIME (合計CPU時間)
  • STMT_EXEC_TIME(実行時間の合計)
  • TOTAL_ACT_WAIT_TIME(待機時間の合計)
  • STMT_TEXT (対象のSQLステートメント)

MON_PKG_CACHE_SUMMARYを使ったほうが見やすいかも。

SELECT * FROM SYSIBMADM.MON_PKG_CACHE_SUMMARY

MON_GET_INDEX

SELECT * FROM TABLE(MON_GET_INDEX(NULL, NULL, -2))

INDEXの使用頻度がわかる。使ってないINDEXなども検出できる。(ただし、XMLインデックスは情報として検出されるがスキャン回数が常に0になる。) 使用していないインデックスを探すために使うのであれば、DB2を非活性化する前に一度取得するぐらいで問題ない。インデックス名はSYSCAT.INDEXESとインデックスID(IID)で見つけることができる。

SELECT * FROM SYSCAT.INDEXES

MON_GET_TABLE

SELECT * FROM TABLE(MON_GET_TABLE('','',-2))

テーブルのselect,update,insert,delete回数などがわかる。OVERFLOW_ACCESSESでオーバーフローしたレコードへのアクセス数がわかるので、REORGしたり、対象テーブルを使っているSQLにインデックスをつけたりして対応したほうがいい。

その他にも様々なモニター表がある。

他にもルーチンの情報やメモリーの情報を返してくれるモニター表があるから、公式でチェックしてみるのもいいと思います。