はじめに
アプリケーションから発行したSQLがうまく動作しない場合、発行したSQLが分かれば調査の手がかりとなります。Oracleのv$sqlを参照すると、実行したSQLの履歴とバインド変数を確認することができます。
ざっくり言うと
- SQLの実行履歴はv$sqlテーブルを見ると分かる。
- 行が多すぎるため、SQLの断片を検索条件に含めると良い。
- バインド変数の確認はv$sql_bind_captureを見ると分かる。
新・門外不出のOracle現場ワザ エキスパートが明かす運用・管理の極意 (DB Selection)
posted with amazlet at 15.06.06
小田 圭二 大塚 信男 五十嵐 建平 谷 敦雄 宮崎 博之 神田 達成 村方 仁
翔泳社
売り上げランキング: 76,494
翔泳社
売り上げランキング: 76,494
直近5分間に実行されたSQLを参照する
以下のクエリで直近5分間に実行されたSQLのIDとSQL文の最初の1000文字を取得できます。
sysユーザでログインします。
conn SYS/pwd AS sysdba
5分以内に実行されたSQLを参照する
SELECT SQL_ID,FIRST_LOAD_TIME,SQL_TEXT FROM V$SQL WHERE FIRST_LOAD_TIME BETWEEN TO_CHAR(SYSDATE - (5 / 24 / 60), 'YYYY-MM-DD/HH24:MI:SS') AND TO_CHAR(SYSDATE, 'YYYY-MM-DD/HH24:MI:SS') ORDER BY FIRST_LOAD_TIME DESC;
実行した結果が以下です。なにやらたくさんSQLが出力されてよく分かりません。
こんなときは、対象のテーブルを絞ります。たとえば、TABLE01に対するクエリだけを抽出する場合は、where句に条件を追加します。
SELECT SQL_ID,FIRST_LOAD_TIME,SQL_TEXT FROM V$SQL WHERE FIRST_LOAD_TIME BETWEEN TO_CHAR(SYSDATE - (5 / 24 / 60), 'YYYY-MM-DD/HH24:MI:SS') AND TO_CHAR(SYSDATE, 'YYYY-MM-DD/HH24:MI:SS') AND SQL_TEXT LIKE UPPER('%TABLE01%') ORDER BY FIRST_LOAD_TIME DESC;
すると、今発行したSQLが抽出されます。
バインド変数を確認する
アプリケーションではwhere句の条件をバインド変数として定義して、アプリケーションから任意の値を渡して実行するケースがあります。
続いて、実行されたSQLのバインド変数を確認してみます。
1.はじめに共有プールをクリアします。
ALTER SYSTEM FLUSH SHARED_POOL;
2.バインド変数が使われているサンプルスクリプトを実行します。
variable vNum NUMBER; declare vCnt NUMBER; begin :vNum := '&id'; select count(*) into vCnt from TABLE01 WHERE ID = :vNum; end; /[f:id:replication:20150606133809p:plain]
3.先ほどのクエリでv$sqlを参照します。
SQLIDが"051cdac56gjcs"であることが分かります。
4.バインド変数を参照する。
バインド変数を参照するには、v$sql_bind_captureを参照します。
SELECT name,value_STRING FROM v$sql_bind_capture WHERE sql_id='051cdac56gjcs';
where句に渡されたバインド変数の値を取得できました。