「なんかおかしいから見てよ!」とか「ぜんぜんSQLが返ってこない!」とか言われてとりあえず、どんな状況なのかまずはV$SESSIONをとっかかりとして、見たくなります。いろいろ動的パフォーマンス・ビューを結合していますので以下簡単に解説します
V$PROCESS | 現在アクティブなプロセスを確認できる。ADDRをキーにV$SESSION(PADDR)と結合できます |
V$TRANSACTION | 現在進行中トランザクションを確認できる。SES_ADDRをキーにV$SESSION(SADDR)と結合できます。 |
V$TEMPSEG_USAGE |
一時セグメントをどのように使っているか確認できる。SESSION_ADDR+SESSION_NUM をキーにV$SESSION(SERIAL# +SADDR)と結合できます。order by やdistinct 等がPGA内だけで収まっている内は良いのですが、PGAだけで賄いきれなくなると一時表領域(一時セグメント)が利用され始めます。当然利用されると遅くなるので観察が必要です。 |
以下例はRAC環境を想定しGV$を利用しているのでINST_IDを意識して結合していますが、シングル環境においてもそのまま利用可能です。
select sysdate as snap_date ,a.INST_ID ,a.SID ,a.SERIAL# ,a.TYPE ,a.MODULE ,a.ACTION ,a.SCHEMANAME ,a.COMMAND ,c.COMMAND_NAME ,a.SQL_ID -- 現在実行中SQL ,a.SQL_CHILD_NUMBER -- 現在実行中SQL ,a.PREV_SQL_ID -- 最後に実行したSQL ,a.PREV_CHILD_NUMBER -- 最後に実行したSQL ,a.STATUS ,a.LAST_CALL_ET -- 今の状態になってからの経過時間 ,a.SQL_EXEC_START ,trunc((sysdate - a.SQL_EXEC_START) * 24 * 60 * 60,2) as "秒" --実行し続けている時間 ,r.SES_ADDR -- トランザクション発生中 ,a.LOCKWAIT -- 待機しているロックアドレス(ロックがない場合NULL) ,a.WAIT_CLASS -- 待機イベントクラス ,a.EVENT ,a.PROGRAM ,a.TERMINAL ,a.MACHINE ----- 一時セグメントを利用しているか ,u.TABLESPACE ,u.SEGTYPE -- 一時セグメントの種別 ,u.BLOCKS -- 割り当てられたブロック数 --PGA情報 ,p.PGA_USED_MEM --現在使用中のPGA ,p.PGA_ALLOC_MEM --現在割り当てられているPGAメモリ ,p.PGA_FREEABLE_MEM --解放できる割当済みPGAメモリ ,p.PGA_MAX_MEM --割り当てられた最大PGAメモリ --,s.USERS_OPENING --,s.USERS_EXECUTING --,s.EXECUTIONS --,s.ROWS_PROCESSED --,s.ELAPSED_TIME --,s.CPU_TIME --,s.FETCHES --,s.SORTS --,substr(s.SQL_TEXT,1, 128) as sql_head from gv$SESSION a left outer join gv$process p on a.INST_ID = p.INST_ID and a.PADDR = p.ADDR --inner join gv$sql s --on a.SQL_ID = s.SQL_ID --and a.SQL_CHILD_NUMBER = s.CHILD_NUMBER --and a.INST_ID = s.INST_ID left outer join gv$transaction r on a.SADDR = r.SES_ADDR and a.INST_ID = r.INST_ID left outer join gV$TEMPSEG_USAGE u on a.SADDR = u.SESSION_ADDR and a.SERIAL# = u.SESSION_NUM and a.INST_ID = u.INST_ID left outer join v$sqlcommand c on a.COMMAND = c.COMMAND_TYPE where 1 = 1 and a.TYPE = 'USER' --and a.SQL_ID='b0xxxxxxxxxgy' or a.PREV_SQL_ID ='b0xxxxxxxxxgy' --and a.status = 'ACTIVE' order by a.INST_ID,a.STATUS,a.SQL_EXEC_START ;
次にV$ACTIVE_SESSION_HISTORY です。V$SESSIONは「今」の状態ですが、 V$ACTIVE_SESSION_HISTORY はSGAにASH用のバッファが確保されており、ここの容量が許す限り保持されているので1時間程度残っている模様、、。(当然インスタンス再起動するとクリアされる)OracleにはASH(Active Session History)といって、V$SESSIONで見れる情報を過去数日(デフォルト8日)SYSAUX内に保持していて、これら情報を確認できるのがDBA_HIST_ACTIVE_SESS_HISTORYです。
SELECT h.INST_ID ,TO_CHAR(h.SAMPLE_TIME, 'YYYY/MM/DD HH24:MI:SS') SAMPLE_TIME ,h.SQL_ID ,h.SESSION_STATE ,h.EVENT ,h.WAIT_TIME ,h.TIME_WAITED ,a.EXECUTIONS ,a.ELAPSED_TIME ,h.SESSION_ID ,h.SESSION_SERIAL# ,substr(t.SQL_TEXT,1,40) SQL_TEXT ,h.PROGRAM ,h.MODULE FROM GV$ACTIVE_SESSION_HISTORY h LEFT JOIN gV$SQLSTATS t ON h.SQL_ID = t.SQL_ID and h.INST_ID = t.INST_ID left outer join gv$sqlarea a on h.INST_ID = a.INST_ID and h.SQL_ID = a.SQL_ID --where t.SQL_ID='dg08q3ykac36s' where h.MODULE ='JDBCTest6' ORDER BY h.SAMPLE_TIME desc ;