Oracleで実行済みSQLを調べるときは、まず V$SQLAREA でSQLの概要と統計を確認し、SQL全文が長くて途中で切れる場合は V$SQLTEXT または V$SQLTEXT_WITH_NEWLINES で分割されたSQL文を復元します。
この記事では、V$SQLAREA と V$SQLTEXT の違い、SQL_ID からSQL本文を確認する方法、長文SQLの復元、実行回数・経過時間・読み取り量の見方、権限不足で見えないときの確認ポイントまで、運用で使う形に絞って解説します。
V$SQLAREA、長いSQL本文の復元は V$SQLTEXT、実行計画まで見るなら DBMS_XPLAN.DISPLAY_CURSOR を組み合わせます。V$SQLAREAとV$SQLTEXTの使い分け早見表
| 目的 | 使うビュー | 見る主な列 |
|---|---|---|
| SQLの一覧と実行統計を見たい | V$SQLAREA |
SQL_ID, SQL_TEXT, EXECUTIONS, ELAPSED_TIME |
| 長文SQLを全文復元したい | V$SQLTEXT |
SQL_ID, PIECE, SQL_TEXT |
| 改行を含めてSQLを見たい | V$SQLTEXT_WITH_NEWLINES |
PIECE, SQL_TEXT |
| 実行計画も確認したい | DBMS_XPLAN.DISPLAY_CURSOR |
SQL_ID, CHILD_NUMBER |
V$SQLAREA だけでもSQL本文は見えますが、列幅や本文長の都合で途中までしか見えないことがあります。SQL全文が必要なときは、V$SQLTEXT を PIECE 順に連結して確認します。
V$SQLAREAとは
V$SQLAREA とは、共有プール上にあるSQLをSQL単位で集約して確認できる動的パフォーマンスビューです。SQL本文の先頭、実行回数、合計経過時間、CPU時間、論理読み取り、物理読み取りなどをまとめて見られます。
「どのSQLが多く実行されているか」「どのSQLが時間を使っているか」「どのSQL_IDを詳しく調べるべきか」を探す入口として使います。ただし、SQL全文の表示や子カーソル単位の詳細確認は、V$SQL や V$SQLTEXT と組み合わせるのが実務的です。
V$SQLTEXTとは
V$SQLTEXT とは、SQL本文を分割行として保持する動的パフォーマンスビューです。長いSQLは1行の SQL_TEXT だけでは途中で切れることがあるため、SQL_ID で絞り、PIECE 順に並べて全文を確認します。
SQLの改行も見たい場合は V$SQLTEXT_WITH_NEWLINES を使います。SQL本文を調査資料へ貼る、アプリから発行されたSQLを復元する、実行計画確認前に対象SQLを特定する、といった用途で役立ちます。
V$SQLAREAで実行済みSQLを一覧表示する
まずは最近実行されたSQLを LAST_ACTIVE_TIME の新しい順に確認します。
SELECT sql_id,
child_number,
executions,
ROUND(elapsed_time / 1000000, 2) AS elapsed_sec,
ROUND(cpu_time / 1000000, 2) AS cpu_sec,
buffer_gets,
disk_reads,
last_active_time,
SUBSTR(sql_text, 1, 120) AS sql_text
FROM v$sqlarea
WHERE last_active_time IS NOT NULL
ORDER BY last_active_time DESC
FETCH FIRST 20 ROWS ONLY;
ELAPSED_TIME と CPU_TIME はマイクロ秒単位です。秒に直すには 1000000 で割ります。遅いSQLの切り分け全体は、遅いSQLを特定する方法も合わせて確認すると流れがつかみやすいです。
Oracle 11gなど FETCH FIRST が使えない環境では、外側で ROWNUM を使います。
SELECT *
FROM (
SELECT sql_id,
executions,
ROUND(elapsed_time / 1000000, 2) AS elapsed_sec,
last_active_time,
SUBSTR(sql_text, 1, 120) AS sql_text
FROM v$sqlarea
WHERE last_active_time IS NOT NULL
ORDER BY last_active_time DESC
)
WHERE ROWNUM <= 20;
古いバージョンのOracleを扱う現場では、12c以降の FETCH FIRST と 11g以前向けの ROWNUM を使い分けると、手元の環境差で詰まりにくくなります。
SQL_IDを指定してV$SQLAREAを見る
SQL_IDが分かっている場合は、対象を絞って統計を確認します。
SELECT sql_id,
child_number,
plan_hash_value,
executions,
rows_processed,
buffer_gets,
disk_reads,
ROUND(elapsed_time / 1000000, 2) AS elapsed_sec,
sql_text
FROM v$sqlarea
WHERE sql_id = '対象のSQL_ID';
同じ SQL_ID でも実行計画や環境条件によって子カーソルが分かれることがあります。詳細を見るときは CHILD_NUMBER も一緒に控えておくと、実行計画確認へつなげやすくなります。
V$SQLTEXTで長文SQLを復元する
V$SQLTEXT はSQL本文を複数行に分割して持っています。PIECE 順に並べると、長いSQLを前から順に確認できます。
SELECT piece,
sql_text
FROM v$sqltext
WHERE sql_id = '対象のSQL_ID'
ORDER BY piece;
SQL*PlusやSQLclでそのまま見れば、分割された本文を順番に追えます。改行付きのSQLを確認したい場合は、V$SQLTEXT_WITH_NEWLINES に切り替えます。
SELECT piece,
sql_text
FROM v$sqltext_with_newlines
WHERE sql_id = '対象のSQL_ID'
ORDER BY piece;
LISTAGGでSQL本文を1行に連結する
レポートに貼り付ける目的なら、LISTAGG でSQL本文を1行にまとめると扱いやすくなります。
SELECT sql_id,
LISTAGG(sql_text, '') WITHIN GROUP (ORDER BY piece) AS full_sql_text
FROM v$sqltext
WHERE sql_id = '対象のSQL_ID'
GROUP BY sql_id;
ただし、非常に長いSQLでは LISTAGG の戻り値長制限に当たることがあります。長大なSQLを安全に出力したい場合は、行分割のまま出力するか、CLOB化する方法を検討してください。
LISTAGG の長さ制限が気になる場合は、XMLAGG でCLOB寄りに連結する方法もあります。
SELECT sql_id,
RTRIM(XMLAGG(XMLELEMENT(e, sql_text) ORDER BY piece)
.EXTRACT('//text()').GETCLOBVAL()) AS full_sql_text
FROM v$sqltext
WHERE sql_id = '対象のSQL_ID'
GROUP BY sql_id;
SQL本文を画面で軽く確認するだけなら PIECE 順の表示で十分です。レポート化や別ツールへの貼り付けが必要なときだけ、連結SQLを使うと扱いやすくなります。
実行時間が長いSQLを探す
平均実行時間が長いSQLを探す場合は、ELAPSED_TIME / EXECUTIONS を見ます。EXECUTIONS が0の行を避けるため、NULLIF で割り算を保護します。
SELECT sql_id,
executions,
ROUND(elapsed_time / 1000000, 2) AS total_elapsed_sec,
ROUND((elapsed_time / NULLIF(executions, 0)) / 1000000, 2) AS avg_elapsed_sec,
buffer_gets,
disk_reads,
SUBSTR(sql_text, 1, 120) AS sql_text
FROM v$sqlarea
WHERE executions > 0
ORDER BY avg_elapsed_sec DESC
FETCH FIRST 20 ROWS ONLY;
合計時間が大きいSQLと、1回あたりが遅いSQLは別物です。頻繁に実行されるSQLは平均が小さくても合計負荷が大きくなるため、TOTAL_ELAPSED_SEC と AVG_ELAPSED_SEC の両方を見るのが実務的です。
読み取り量が多いSQLを探す
CPU時間よりもI/Oやバッファ読み取りが問題になっていそうな場合は、BUFFER_GETS や DISK_READS で並べ替えます。
SELECT sql_id,
executions,
buffer_gets,
ROUND(buffer_gets / NULLIF(executions, 0), 2) AS buffer_gets_per_exec,
disk_reads,
SUBSTR(sql_text, 1, 120) AS sql_text
FROM v$sqlarea
WHERE executions > 0
ORDER BY buffer_gets_per_exec DESC
FETCH FIRST 20 ROWS ONLY;
読み取り量が多いSQLは、実行計画や索引の使われ方を確認します。実行計画の読み方は DBMS_XPLAN完全ガイド や EXPLAIN PLAN完全ガイド に進むとよいです。
現在実行中のセッションからSQL_IDを拾う
今まさに動いているSQLを追う場合は、V$SESSION から SQL_ID を取得して、V$SQLAREA や V$SQLTEXT へつなぎます。
SELECT s.sid,
s.serial#,
s.username,
s.status,
s.sql_id,
s.event,
s.seconds_in_wait
FROM v$session s
WHERE s.username IS NOT NULL
AND s.sql_id IS NOT NULL
ORDER BY s.last_call_et DESC;
セッションやロック調査と組み合わせる場合は、セッションの確認・強制切断方法も関連します。待機イベントを見て原因を切り分けるなら、待機イベント完全ガイドも役立ちます。
V$SQLAREAでよく見る列
| 列 | 意味 | 見るポイント |
|---|---|---|
SQL_ID |
SQLを識別するID | 実行計画・SQL本文確認のキーにする |
CHILD_NUMBER |
子カーソル番号 | 同じSQL_IDで複数計画がある場合に重要 |
EXECUTIONS |
実行回数 | 平均値を出すときの分母にする |
ELAPSED_TIME |
合計経過時間 | マイクロ秒単位。秒換算して見る |
CPU_TIME |
合計CPU時間 | CPU負荷が高いSQLの候補を見る |
BUFFER_GETS |
論理読み取り | 1回あたりの読み取り量を見る |
DISK_READS |
物理読み取り | I/O負荷の候補を見る |
LAST_ACTIVE_TIME |
最後にアクティブだった時刻 | 直近のSQLを探す |
権限不足で見えないとき
V$SQLAREA や V$SQLTEXT は動的パフォーマンスビューです。参照権限がないユーザーでは、エラーになったり、必要な行が見えなかったりします。
-- 権限例。付与はDBAに依頼してください。 GRANT SELECT_CATALOG_ROLE TO app_user; -- または必要なビューだけ個別に付与 GRANT SELECT ON v_$sqlarea TO app_user; GRANT SELECT ON v_$sqltext TO app_user;
権限確認の考え方は、Oracleのユーザ権限を確認する方法で整理しています。運用環境では、必要最小限の権限で参照できるようにDBAと調整してください。
V$SQLAREAだけで判断しない注意点
- 共有プールから消えたSQLは見えないことがある
- 統計値はインスタンス起動後やカーソル生成後からの累積である
- 同じSQL_IDでも子カーソルごとに実行計画が違うことがある
- 過去の問題調査ではAWRやASHのほうが向いている場合がある
V$SQLAREA は「今メモリ上にあるSQLを見る」ための入口です。長期的な傾向や過去時点の調査では、AWR・ASH・SQL Tuning Advisorも合わせて使います。SQL Tuning Advisor完全ガイドも次の確認先になります。
関連ページ
よくある質問
V$SQLAREAとは何ですか?
V$SQLAREA は、共有プール上のSQLをSQL単位で集約し、実行回数・経過時間・CPU時間・読み取り量などを確認する動的パフォーマンスビューです。
V$SQLTEXTとは何ですか?
V$SQLTEXT は、SQL本文を PIECE ごとの分割行として確認するビューです。長文SQLを全文確認したいときに使います。
V$SQLAREAとV$SQLの違いは何ですか?
V$SQL は子カーソル単位の情報を見やすく、V$SQLAREA はSQL単位で集約された統計を見やすいビューです。詳細に追うときは両方を使います。
V$SQLTEXTは何に使いますか?
長いSQL文を分割行として確認するために使います。SQL_ID で絞り、PIECE 順に並べます。
SQL_TEXTが途中で切れるのはなぜですか?
表示列の長さやビューの列仕様により、全文が見えないことがあります。全文確認には V$SQLTEXT や V$SQLTEXT_WITH_NEWLINES を使います。
ELAPSED_TIMEの単位は何ですか?
マイクロ秒です。秒として見たい場合は 1000000 で割ります。
過去に実行されたSQLが見つからないことはありますか?
あります。共有プールから消えたSQLは V$SQLAREA では見えません。過去調査にはAWRやASHを検討します。
本番環境で誰でも見られるビューですか?
通常は権限が必要です。SELECT_CATALOG_ROLE や対象ビューへの個別権限が必要になるため、DBAに確認してください。
まとめ
V$SQLAREA は、実行済みSQLの概要、実行回数、経過時間、読み取り量を確認する入口です。一方で、SQL本文が長い場合は V$SQLTEXT を PIECE 順に確認して全文を復元します。
調査の流れとしては、V$SESSION や V$SQLAREA で SQL_ID を見つけ、V$SQLTEXT で本文を確認し、必要に応じて DBMS_XPLAN.DISPLAY_CURSOR で実行計画へ進む、という順番にすると迷いにくくなります。
