「さっきどんなSQLが実行されたか確認したい」「重いSQLを特定してチューニングしたい」――Oracleの運用でこのような場面は頻繁に発生します。そんなときに役立つのが V$SQLビュー です。
V$SQLはOracle共有プール上にキャッシュされたSQLの情報を保持するビューで、実行済みSQLの検索・実行統計の確認・パフォーマンス分析まで幅広く活用できます。この記事では、基本的な使い方から実務で使えるクエリパターンまで体系的に解説します。
この記事で学べること
- V$SQLビューの概要とV$SQLAREA・V$SQLTEXTとの違い
- 直前に発行されたSQLをLAST_ACTIVE_TIMEで取得する方法
- 特定ユーザー・スキーマ・キーワードでSQLを絞り込む方法
- 実行回数・CPU時間・実行時間でランキングするTop SQLクエリ
- V$SESSIONと結合して現在実行中のSQLを確認する方法
- V$SQLの主要列の意味と実務での活用ポイント
V$SQLビューとは
V$SQLはOracle Databaseの共有プール(Shared Pool)にキャッシュされたSQLカーソルの情報を格納するビューです。SQLが実行されると共有プール上にキャッシュされ、V$SQLから参照できるようになります。
重要:V$SQLは動的パフォーマンスビューであり、データベース再起動・共有プールのフラッシュ(ALTER SYSTEM FLUSH SHARED_POOL)・キャッシュ容量不足によるエージングアウトでデータが消える点に注意してください。永続的な履歴が必要な場合はAWR(DBA_HIST_SQLSTAT)を使用します。
V$SQL・V$SQLAREA・V$SQLTEXTの違い
| ビュー | 内容 | 主な用途 |
|---|---|---|
V$SQL |
子カーソル単位の統計(バインド変数値の違いで分かれる) | 詳細な実行統計・個別SQL分析 |
V$SQLAREA |
同一SQL_IDの子カーソルを集約した統計 | SQL単位の集計・Top SQL |
V$SQLTEXT |
SQLテキストが64文字ごとに分割されて格納 | 4000文字を超える長いSQLの全文取得 |
ポイント:通常の調査では V$SQL を使えば十分です。4000文字を超える長いSQLを確認したい場合は V$SQLTEXT、複数の子カーソルをまとめて分析したい場合は V$SQLAREA を使いましょう。
直前に発行されたSQLを確認する
最後に実行されたSQL(全ユーザー)
LAST_ACTIVE_TIME(最後にアクティブだった時刻)が最大のレコードを取得することで、直前に実行されたSQLを確認できます。
直近N件のSQLを確認する
最後の1件だけでなく、直近の複数件を確認したい場合は ROWNUM で件数を絞ります。
実務で使えるクエリパターン
特定ユーザーが実行したSQLを確認する
PARSING_SCHEMA_NAME(解析時のスキーマ名)で絞り込めます。
特定のテーブル・キーワードを含むSQLを検索する
SQL_TEXTに対して LIKE 検索で絞り込めます。ただし SQL_TEXT は先頭1000文字のみ格納されるため、全文検索には V$SQLTEXT と組み合わせます。
指定時間帯に実行されたSQLを確認する
パフォーマンス分析:Top SQLを特定する
実行時間が長いSQLランキング(Top 10)
チューニング対象を探すときは ELAPSED_TIME(合計実行時間)や CPU_TIME でソートします。実行回数で割った「1回あたりの平均時間」も合わせて確認すると効果的です。
I/O負荷が高いSQLランキング(BUFFER_GETS / DISK_READS)
実行回数が多いSQLランキング
頻繁に実行されるSQLはチューニング効果が大きいため、実行回数でランキングするのも有効です。
V$SESSIONと結合:現在実行中のSQLを確認する
V$SQLだけでは「今まさに実行中のSQL」を特定できません。V$SESSIONと結合することで、現在アクティブなセッションが実行しているSQLをリアルタイムで確認できます。
ポイント:結合条件に sql_child_number を必ず含めてください。V$SQLは同一SQL_IDで複数の子カーソルを持つため、sql_id のみで結合すると行が重複します。
V$SQLの主要列一覧
| 列名 | データ型 | 説明 |
|---|---|---|
SQL_ID |
VARCHAR2(13) | SQLのユニーク識別子。バインド変数が異なっても同じ値になる |
SQL_TEXT |
VARCHAR2(1000) | SQLテキスト(先頭1000文字) |
LAST_ACTIVE_TIME |
DATE | 最後にアクティブだった時刻(最後の実行時刻の目安) |
EXECUTIONS |
NUMBER | このカーソルが共有プールにキャッシュされてからの実行回数 |
ELAPSED_TIME |
NUMBER | 合計実行時間(マイクロ秒)。÷1000000で秒換算 |
CPU_TIME |
NUMBER | 使用したCPU時間の合計(マイクロ秒) |
BUFFER_GETS |
NUMBER | バッファキャッシュからの論理読み取りブロック数(合計) |
DISK_READS |
NUMBER | ディスクからの物理読み取りブロック数(合計)。多いとI/Oボトルネックの可能性 |
PARSE_CALLS |
NUMBER | パース呼び出し回数。多いとハードパースが頻発している可能性 |
ROWS_PROCESSED |
NUMBER | 処理(返却)した行数の合計 |
PARSING_SCHEMA_NAME |
VARCHAR2(128) | SQLをパースしたスキーマ名 |
CHILD_NUMBER |
NUMBER | 子カーソル番号(V$SESSIONとの結合に使用) |
V$SQL使用上の注意点
| 注意事項 | 詳細 |
|---|---|
| データが消える | DB再起動・共有プールフラッシュ・容量不足によるエージングアウトでキャッシュが消える。過去のSQLを永続的に保持したい場合はAWR(DBA_HIST_SQLSTAT)を使う |
| SQL_TEXTは1000文字まで | 1000文字を超えるSQLは切り捨てられる。全文は V$SQLTEXT(PIECE列を ORDER BY PIECE で結合)から取得する |
| SELECT権限が必要 | V$SQLはデフォルトでSYS・DBAロールのみ参照可能。一般ユーザーには GRANT SELECT ON V_$SQL TO ユーザー; で権限を付与する |
| 自身のSQLが混入する | V$SQLを検索するSQLも V$SQL に記録される。WHERE UPPER(sql_text) NOT LIKE '%V$SQL%' で除外する |
まとめ
V$SQLビューはOracle運用・チューニングの現場で欠かせないツールです。各クエリの用途を整理しておきましょう。
| やりたいこと | 使うクエリ・列 |
|---|---|
| 直前に実行されたSQLを確認 | WHERE last_active_time = (SELECT MAX...) |
| 特定ユーザーのSQLを確認 | WHERE parsing_schema_name = 'USER' |
| テーブル名でSQLを検索 | WHERE UPPER(sql_text) LIKE '%TABLE%' |
| 重いSQLをランキング | ORDER BY elapsed_time DESC + ROWNUM |
| I/O負荷の高いSQLを特定 | ORDER BY disk_reads DESC |
| 現在実行中のSQLをリアルタイム確認 | V$SESSION JOIN V$SQL + WHERE status='ACTIVE' |
V$SQLは共有プールのキャッシュに依存するため、過去の長期履歴はAWRスナップショット(DBA_HIST_SQLSTAT)で補完するのが実務での定石です。両方を使い分けて、効率的なSQL調査とパフォーマンスチューニングに役立ててください。