Monday, July 27, 2026

How to Troubleshoot high db file sequential read waits in Oracle Database ?

If you see high db file sequential read waits, it usually means sessions are doing single-block physical reads (typically index lookups, nested loop joins, row-by-row access, or reading blocks that are not in the buffer cache).

The objective is:

  1. Identify which SQLs are generating the reads.
  2. Identify which users/sessions are running them.
  3. Verify whether the issue is SQL, indexing, buffer cache, or storage latency.

Step 1: Check Current Sessions Waiting on db file sequential read

SELECT
s.sid,
s.serial#,
s.username,
s.machine,
s.program,
s.sql_id,
s.event,
s.seconds_in_wait,
s.state,
sw.p1 "FILE#",
sw.p2 "BLOCK#"
FROM v$session s
JOIN v$session_wait sw
ON s.sid = sw.sid
WHERE s.event = 'db file sequential read'
ORDER BY s.seconds_in_wait DESC;

This tells you:

  • Who is waiting
  • Which SQL_ID is involved
  • Which file/block Oracle is reading

Step 2: Find SQLs Causing Most Physical Reads

Current cache:

SELECT *
FROM
(
SELECT
sql_id,
parsing_schema_name,
executions,
buffer_gets,
disk_reads,
ROUND(disk_reads/NULLIF(executions,0),2) reads_per_exec,
SUBSTR(sql_text,1,100) sql_text
FROM v$sql
WHERE disk_reads > 0
ORDER BY disk_reads DESC
)
WHERE ROWNUM <= 20;

Focus on:

disk_reads
reads_per_exec

High values indicate likely contributors.


Step 3: Identify Top Users Generating Physical Reads

SELECT
s.username,
SUM(q.disk_reads) disk_reads,
COUNT(*) sql_count
FROM v$session s
JOIN v$sql q
ON s.sql_id = q.sql_id
WHERE s.username IS NOT NULL
GROUP BY s.username
ORDER BY disk_reads DESC;


Step 4: Check Historical SQLs from AWR

Top SQLs causing reads:

SELECT *
FROM
(
SELECT
sql_id,
SUM(disk_reads_delta) disk_reads,
SUM(executions_delta) executions,
ROUND(
SUM(disk_reads_delta) /
NULLIF(SUM(executions_delta),0),
2
) reads_per_exec
FROM dba_hist_sqlstat
GROUP BY sql_id
ORDER BY SUM(disk_reads_delta) DESC
)
WHERE ROWNUM <= 20;

Get SQL text:

SELECT sql_id,
sql_text
FROM dba_hist_sqltext
WHERE sql_id = '&SQL_ID';


Step 5: Find SQLs Waiting on db file sequential read

Historical AWR:

SELECT
ash.sql_id,
ash.user_id,
COUNT(*) samples
FROM dba_hist_active_sess_history ash
WHERE ash.event = 'db file sequential read'
GROUP BY ash.sql_id, ash.user_id
ORDER BY samples DESC;

Resolve user names:

SELECT user_id, username
FROM dba_users;


Step 6: Current ASH Analysis

If licensed for Diagnostics Pack:

SELECT
sql_id,
session_id,
user_id,
COUNT(*) samples
FROM v$active_session_history
WHERE event='db file sequential read'
GROUP BY sql_id, session_id, user_id
ORDER BY samples DESC;

Top SQL causing waits appears at the top.


Step 7: Check Storage Latency

Sometimes the SQL is fine but storage is slow.

SELECT
file_no,
filetype_name,
small_read_reqs,
ROUND(
small_read_servicetime /
NULLIF(small_read_reqs,0),
2
) avg_read_ms
FROM v$iostat_file
ORDER BY avg_read_ms DESC;

Guidelines:

< 1 ms Excellent
1-5 ms Good
5-10 ms Acceptable
>10 ms Investigate
>20 ms Critical


Step 8: Check Which Objects Are Being Read

From ASH:

SELECT
current_obj#,
COUNT(*) samples
FROM v$active_session_history
WHERE event='db file sequential read'
GROUP BY current_obj#
ORDER BY samples DESC;

Object details:

SELECT
owner,
object_name,
object_type
FROM dba_objects
WHERE object_id=&OBJECT_ID;

This often identifies a hot table or index.


Step 9: Check Execution Plan

For the top SQL:

SELECT *
FROM TABLE(
DBMS_XPLAN.DISPLAY_CURSOR(
'&SQL_ID',
NULL,
'ALLSTATS LAST'
));

Look for:

TABLE ACCESS BY INDEX ROWID
INDEX RANGE SCAN
INDEX UNIQUE SCAN
NESTED LOOP

These are the most common sources of db file sequential read.


Step 10: Determine the Root Cause

Case 1: High disk reads + poor index

Check missing indexes:

SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&SQL_ID'));

Symptoms:

  • Millions of rows visited
  • Many index lookups

Action:

  • Create/modify index
  • Review predicates

Case 2: High Reads per Execution

disk_reads/executions

Example:

Disk Reads : 10,000,000
Executions : 50
Reads/Exec : 200,000

Action:

  • Tune SQL
  • Reduce rows accessed

Case 3: Good SQL but Slow Read Time

Check:

SELECT event,
ROUND(time_waited_micro/total_waits/1000,2) avg_ms
FROM v$system_event
WHERE event='db file sequential read';

If:

avg_ms > 10

Investigate:

  • Storage
  • ASM
  • SAN
  • Multipathing
  • Exadata Cells

One Query I Use First as a DBA

SELECT
ash.sql_id,
u.username,
COUNT(*) ash_samples
FROM dba_hist_active_sess_history ash
LEFT JOIN dba_users u
ON ash.user_id = u.user_id
WHERE ash.event = 'db file sequential read'
GROUP BY ash.sql_id, u.username
ORDER BY ash_samples DESC
FETCH FIRST 20 ROWS ONLY;

Then:

SELECT sql_text
FROM dba_hist_sqltext
WHERE sql_id='&SQL_ID';

This quickly identifies which SQL and which user are responsible for the majority of db file sequential read waits.


Stale Statistics


SELECT owner,
table_name,
stale_stats
FROM dba_tab_statistics
WHERE stale_stats='YES';


Poor Buffer Cache Hit Ratio


SELECT name, value
FROM v$sysstat
WHERE name IN (
'physical reads',
'db block gets',
'consistent gets'
);


SELECT
ROUND((1 - (
physical_reads /
(db_block_gets + consistent_gets)
))*100,2) hit_ratio
FROM v$buffer_pool_statistics;

Hot Objects

Find objects frequently involved:


SELECT
o.owner,
o.object_name,
COUNT(*) samples
FROM v$active_session_history ash,
dba_objects o
WHERE ash.current_obj# = o.object_id
AND ash.event='db file sequential read'
GROUP BY o.owner,o.object_name
ORDER BY samples DESC;

Slow Storage

Query:


SELECT
file_no,
filetype_name,
ROUND(
small_read_servicetime/
NULLIF(small_read_reqs,0),
2
) avg_read_ms
FROM v$iostat_file
ORDER BY avg_read_ms DESC;


Decide:

  • Missing index → Create/tune index
  • Bad plan → Gather stats / SQL tuning
  • High reads per execution → SQL rewrite
  • High latency → Storage team
  • Frequent rereads → Increase cache

No comments:

Post a Comment

How to know and troubleshoot how much time a session has waited on each wait event ?

  If you want to know how much time a session has waited on each wait event , here are the most useful queries. 1. Current Session Wait Info...