Databases 11 min read

Why Oracle Tablespace Queries Stall and How to Resolve Them Fast

The article walks through two common Oracle performance problems—slow tablespace‑information queries and sluggish ASH data collection—explaining root causes, showing diagnostic steps, and providing exact SQL and PL/SQL scripts to gather statistics, clean up partitions, and restore fast query response.

dbaplus Community
dbaplus Community
dbaplus Community
Why Oracle Tablespace Queries Stall and How to Resolve Them Fast

1. Tablespace Information Query Slowness

A client reported that a custom query against DBA_FREE_SPACE stopped returning results, causing anxiety about unknown tablespace usage. The typical reasons are stale dictionary statistics and an excess of objects in the recycle bin.

Remediation steps:

exec dbms_stats.gather_fixed_objects_stats;
exec dbms_stats.gather_dictionary_stats(degree => 8, cascade => true);
purge recyclebin;

After executing these commands, the query returned promptly.

The original SQL used by the client was:

SELECT UPPER(F.TABLESPACE_NAME) AS "表空间名称",
       ROUND(D.AVAILB_BYTES, 2) AS "表空间大小(G)",
       ROUND(D.MAX_BYTES, 2) AS "最终表空间大小(G)",
       ROUND((D.AVAILB_BYTES - F.USED_BYTES), 2) AS "已使用空间(G)",
       TO_CHAR(ROUND((D.AVAILB_BYTES - F.USED_BYTES) / D.AVAILB_BYTES * 100, 2), '999.99') AS "使用比",
       ROUND(F.USED_BYTES, 6) AS "空闲空间(G)",
       F.MAX_BYTES AS "最大块(M)"
FROM   (SELECT TABLESPACE_NAME,
               ROUND(SUM(BYTES) / (1024*1024*1024), 6) USED_BYTES,
               ROUND(MAX(BYTES) / (1024*1024*1024), 6) MAX_BYTES
        FROM   SYS.DBA_FREE_SPACE
        GROUP BY TABLESPACE_NAME) F,
       (SELECT DD.TABLESPACE_NAME,
               ROUND(SUM(DD.BYTES) / (1024*1024*1024), 6) AVAILB_BYTES,
               ROUND(SUM(DECODE(DD.MAXBYTES,0,DD.BYTES,DD.MAXBYTES)) / (1024*1024*1024),6) MAX_BYTES
        FROM   SYS.DBA_DATA_FILES DD
        GROUP BY DD.TABLESPACE_NAME) D
WHERE  D.TABLESPACE_NAME = F.TABLESPACE_NAME
ORDER BY 4 DESC;

Initially the script hung; after gathering fresh statistics and purging the recycle bin, the query completed in seconds.

2. ASH Data Collection Slowness

Another client observed that a monitoring SQL which collects Active Session History (ASH) data took up to four minutes on one database, while the same statement finished within a second on other instances.

Using an AWR monitor report, the wait events were identified: ~55% "read by other session" and ~36% GC‑related waits, indicating heavy I/O reads in a RAC environment.

Monitor report showing wait events
Monitor report showing wait events

The I/O originated mainly from the WRH$_ACTIVE_SESSION_HISTORY table (54% from one partition, 46% from another). The table should be partitioned and automatically cleaned, but in this case partitions accumulated data.

To verify partition information, the following PL/SQL block was run:

set serveroutput on
declare
  cursor cur_part is
    select partition_name from dba_tab_partitions
    where table_name = 'WRH$_ACTIVE_SESSION_HISTORY';
  query1 varchar2(200);
  query2 varchar2(200);
  type partrec is record (snapid number, dbid number);
  type partlist is table of partrec;
  outlist partlist;
begin
  dbms_output.put_line('PARTITION NAME  SNAP_ID  DBID');
  dbms_output.put_line('--------------------------- ------- ----------');
  for part in cur_part loop
    query1 := 'select min(snap_id), dbid from sys.WRH$_ACTIVE_SESSION_HISTORY partition ('||part.partition_name||') group by dbid';
    execute immediate query1 bulk collect into outlist;
    if outlist.count > 0 then
      for i in outlist.first..outlist.last loop
        dbms_output.put_line(part.partition_name||' Min '||outlist(i).snapid||' '||outlist(i).dbid);
      end loop;
    end if;
    query2 := 'select max(snap_id), dbid from sys.WRH$_ACTIVE_SESSION_HISTORY partition ('||part.partition_name||') group by dbid';
    execute immediate query2 bulk collect into outlist;
    if outlist.count > 0 then
      for i in outlist.first..outlist.last loop
        dbms_output.put_line(part.partition_name||' Max '||outlist(i).snapid||' '||outlist(i).dbid);
      end loop;
    end if;
    dbms_output.put_line('---');
  end loop;
end;
/

The output confirmed that partitions existed but were not being automatically created or cleaned.

Cleanup commands used were:

exec dbms_workload_repository.drop_snapshot_range(low_snap_id => 2810, high_snap_id => 18000);
alter table WRH$_ACTIVE_SESSION_HISTORY shrink space;

Because the shrink operation took long (several hours), the author also suggested truncating the large partition directly (with the risk of losing some performance data):

alter table sys.wrh$_active_session_history truncate partition WRH$_ACTIVE_xxxx_xxxx update global indexes;

After these actions, the ASH‑collecting SQL returned instantly. The author notes that on older Oracle versions (11.2.0.2) a hidden parameter _swrf_test_action = 72 may need to be set, and that patching to 12.1.0.1 or later can resolve automatic partition‑creation issues.

Patch version information
Patch version information
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

SQLperformance tuningOracleTablespaceASH
dbaplus Community
Written by

dbaplus Community

Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.