Query Wait Events by Session with Oracle V$SESSION_WAIT
Query Wait Events by Session with Oracle V$SESSION_WAIT
Purpose
V$SESSION_WAIT is the real-time view that shows what each Oracle session is waiting on this very second. For every session it exposes the wait event name, how long the session has been in that wait, and three event-specific parameters (P1, P2, P3) that pinpoint the resource — a file and block number, a lock type, a latch address. It is the view to reach for when the database "feels slow right now" and you need the current state, not a post-mortem from AWR.
On its own the view gives you SID and event; joined to V$SESSION it gives you the username, the program, the machine, and the SQL the session is running. That join turns a list of anonymous wait events into a list of named users stuck on named resources — the difference between "there is contention" and "the payroll batch on app-server-3 is blocked on a row lock."
The query below is read-only and built for incident response: run it, read the top rows, and you know where the database's time is going.
Code
1SET LINESIZE 220
2COLUMN username FORMAT A16
3COLUMN event FORMAT A34
4COLUMN wait_class FORMAT A12
5COLUMN secs FORMAT 999999
6
7SELECT s.sid,
8 s.serial#,
9 s.username,
10 w.event,
11 w.wait_class,
12 w.seconds_in_wait AS secs,
13 w.p1, w.p2, w.p3,
14 s.sql_id
15FROM v$session_wait w
16 JOIN v$session s
17 ON s.sid = w.sid
18WHERE s.username IS NOT NULL -- skip background processes
19AND w.wait_class <> 'Idle' -- skip idle waits
20ORDER BY w.seconds_in_wait DESC;
Code Breakdown
v$session_wait w— one row per session, showing its current or most recent wait. Theeventcolumn names the wait (for exampledb file sequential read,enq: TX - row lock contention,log file sync).seconds_in_wait— how long the session has been in the current wait. Ordering by it descending surfaces the most stuck sessions first.wait_class— a coarse bucket for the event:User I/O,Concurrency,Application,Commit,Network, and so on. Filtering outIdleremoves sessions that are simply waiting for the next client request and would otherwise dominate the output.p1,p2,p3— the event-specific parameters. Their meaning depends on the event: fordb file sequential readthey are file number, block number, and block count; for an enqueue wait they encode the lock type and mode.V$EVENT_NAMEdocuments what each parameter means per event.- The join to
v$session s— addsusername,serial#, andsql_id.serial#together withsididentifies the exact session forALTER SYSTEM KILL SESSION;sql_idlinks toV$SQLfor the statement text. WHERE s.username IS NOT NULL— filters out Oracle background processes (whose username is null), leaving only real user sessions.
Key Points
V$SESSION_WAITshows the current wait. From Oracle 10g onward, the same columns are also exposed directly onV$SESSION(theevent,wait_class, andseconds_in_waitcolumns), so a single scan ofV$SESSIONcan replace the join — butV$SESSION_WAITremains the canonical, explicit source.- A session showing an
Idlewait class (for exampleSQL*Net message from client) is not a problem — it is waiting for the user, not for the database. Always filterIdleout when hunting for contention. seconds_in_waitresets each time the session enters a new wait. A small value on a busy event means the session is cycling through many short waits, not that it just started.- The
statecolumn (WAITING,WAITED KNOWN TIME,WAITED SHORT TIME) tells you whether the session is in the wait now or has just come out of one. OnlyWAITINGis a live, in-progress wait. - For a session blocked by another session,
V$SESSION.blocking_sessionnames the holder directly — often faster than decodingP1/P2/P3by hand.
Insights and Best Practices
Start with wait class, then drill into the event
Grouping the output by wait_class tells you the shape of the problem before you read individual events. A screen full of User I/O points at storage or a bad plan doing too many reads; a screen full of Concurrency points at latches or buffer contention; Application waits are almost always row locks from the application's own logic.
Decode P1/P2/P3 with V$EVENT_NAME
The parameter columns are only useful if you know what they mean for the event in question. Join to V$EVENT_NAME (or look the event up there) to get the parameter1/parameter2/parameter3 labels. For db file sequential read, turning P1 and P2 into a file and block number lets you map the wait back to a specific segment via DBA_EXTENTS.
Use it as a sampler, not a one-shot
A single query is a snapshot. Run it a few times a few seconds apart during an incident, or wrap it in a short polling loop, to see whether sessions are stuck on the same event (a genuine stall) or moving through different events (normal, busy work). This poor-man's sampling mirrors what Active Session History does continuously on Enterprise Edition with the Diagnostics Pack.
Know when to escalate to ASH and AWR
V$SESSION_WAIT is current-state only; it has no history. When you need "what was the system waiting on at 02:00 last night," that is Active Session History (V$ACTIVE_SESSION_HISTORY) and AWR territory. Use the live view to triage now, and the history views to investigate what already happened.
When to Use This Check
- During a live "the database is slow" incident, to see where time is being spent right now.
- To find which sessions are blocked and on what, before deciding whether to kill a session.
- To confirm a suspected I/O problem by counting sessions on
db fileread events. - As a periodic sampler that records the active wait profile for later trend analysis.
Troubleshooting Common Issues
If the query returns only idle waits after filtering, the database genuinely is not contended — look at the application tier or the network instead. If many sessions share one event such as buffer busy waits or latch: cache buffers chains, decode P1/P2 to find the hot block or latch and investigate the object behind it. If a session sits on enq: TX - row lock contention for a long time, follow V$SESSION.blocking_session to the holder and decide whether that session should be committed, rolled back, or killed. Remember that seconds_in_wait is meaningful only when state = 'WAITING'; for a session that has already left the wait, the value reflects the last completed wait, not an ongoing one.
References
- V$SESSION_WAIT - Oracle Database Reference 19c - Official definition of the view, including event, wait_class, seconds_in_wait, state, and the P1/P2/P3 parameters.
- V$SESSION - Oracle Database Reference 19c - The session view that supplies username, serial#, sql_id, and blocking_session for the join.
- V$SESSION_EVENT - Oracle Database Reference 19c - Cumulative per-session wait totals, the aggregate counterpart to the point-in-time V$SESSION_WAIT.
- Active Session History (ASH) - oracle-base.com - Explains how ASH samples active sessions and wait events continuously, the history layer above this live view.
- How to find active sessions in Oracle Database - dbaclass.com - A practical recipe for listing active sessions and their current wait events with ready-to-run SQL.
Posts in this series
- Oracle: Find Wait Events by Datafile with x$kcbfwait
- Oracle Top 10 Hot Objects by Touch Count with x$bh
- Oracle Latch Contention Analysis with v$system_event
- Oracle Segment Waits Analysis with v$segment_statistics
- Oracle v$statname and v$sysstat Performance Stats
- Oracle Buffer Busy Waits Analysis with v$session_wait
- Analyzing Oracle 'Data Block' Waits with v$waitstat
- Identifying Oracle Database Hot Blocks Using v$system_event
- Query Wait Events by Session with Oracle V$SESSION_WAIT