Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Tips Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS Access
SQL Scripts & Samples
» Database Forum
» Slideshows
» Sitemap
Free Newsletters:

News Via RSS Feed

Database Journal |DBA Support |SQLCourse |SQLCourse2

Featured Database Articles


Posted Jun 7, 2003

Disk Sorts - A Subtle Threat to Database Performance - Page 2

By DatabaseJournal.com Staff

by Robin Schumacher

Are Disk Sorts Affecting Your Database?

How can you tell if disk sorts are occurring on your system and causing an adverse effect on the performance of your database? There are a couple of routes you can take to determine if disk sorts are indeed present on your database:

  • Examine the memory/disk sort ratio
  • View wait events that may indicate disk sort activity
  • Check session activity regarding disk sort operations

The place to start is with a ratio of memory vs. disk sorts to see if disk sorts are coming into play on your database. The basic query to use is the following:

       0,1,(a.VALUE + b.VALUE)),2) "Percent memory sorts"
FROM   v$sysstat a, 
       v$sysstat b
WHERE  a.name = 'sorts (disk)'
AND    b.name = 'sorts (memory)'
Percent memory sorts

Note that if Oracle has been up a long time, the cumulative numbers for memory sorts may hide more recent occurrences of disk sorts. What you hope to see (whether just using cumulative metrics or delta-based statistics) is a high value - at least 95% or more. Lower percentages could indicate a current or growing disk sort problem.

From a wait event perspective, there aren't really wait events that are solely devoted to disk sort activity. However, from past experience I can tell you that databases I've been involved with that suffered from disk sort activity seem to show a high percentage of time waited for the direct path read and direct path write events. A wait-based query you can use to check for these events is the following:

select event,
       round(100 * (total_waits / sum_waits),2) pct_waits,
       round(100 * (time_wait_sec / greatest(sum_time_waited,1)),2)
       round(100 * (total_timeouts / greatest(sum_timeouts,1)),2) 
(select event,
       round((time_waited / 100),2) time_wait_sec,
       round((average_wait / 100),2) average_wait_sec
from sys.v_$system_event
where event in ('direct path read','direct path write')),
(select sum(total_waits) sum_waits,
        sum(total_timeouts) sum_timeouts,
        sum(round((time_waited / 100),2)) sum_time_waited
 from sys.v_$system_event
 where event not in 
 ('lock element cleanup', 
 'pmon timer', 
 'rdbms ipc message',
 'rdbms ipc reply',
 'smon timer', 
 'SQL*Net message from client', 
 'SQL*Net break/reset to client',
 'SQL*Net message to client',
 'SQL*Net more data from client',
 'dispatcher timer',
 'Null event',
 'parallel query dequeue wait',
 'parallel query idle wait - Slaves',
 'pipe get',
 'PL/SQL lock timer',
 'slave wait',
 'virtual circuit status',
 'WMON goes to sleep') AND 
 event not like 'DFS%' AND 
 event not like 'KXFX%')
order by 2 desc, 1 asc  

Output from a system suffering from disk sorts might look like this:

Notice the high percentages of time waited attributed to these two events over all other events.

One other thing you can do at the global database level is to check the I/O activity of your temporary tablespaces that are devoted to disk sort operations. A query like this can be used:

select  c.name tablespace_name,
from    sys.v_$datafile a, 
        sys.v_$filestat b,
        sys.ts$ c ,
        sys.file$ d
where   ( a.file# = b.file#) and 
        ( a.file# = d.file#) and
        d.ts# = c.ts# 
group by c.name 
union all
select  c.name tablespace_name,
from    sys.v_$tempfile a,
        sys.v_$tempstat b,
        sys.ts$ c ,
        sys.x$kccfn v, 
        sys.x$ktfthc hc 
where   a.file# = b.file# and 
        a.file# = hc.ktfthctfno and
        hc.ktfthctsn = c.ts# and
        v.fntyp = 7 and
        v.fnnam is not null  and 
        v.fnfno = hc.ktfthctfno  and 
        hc.ktfthctsn = c.ts#
group by c.name
order by 1

Output from a database with high disk sort activity might look like this:

Notice the high numbers of reads and writes for the TEMP and TEMP2 tablespaces above. This indicates a lot of disk sort activity. You should also check the read and write times to see if Oracle is experiencing I/O delays in reading from and writing to the temporary tablespaces.

From the global database level, you can move into examining disk sort activity at the session level to see if one or more sessions are causing the bulk of disk sorts. A query I like to use for this is the following:

select  b.sid sid,
        decode (b.username,null,e.name,b.username) user_name,
        b.machine machine_name,
        to_char(logon_time,'dd-mon-yy hh:mi:ss pm') logon_time,
        sum(decode(c.name,'sorts (disk)',value,0)) disk_sorts,
        sum(decode(c.name,'sorts (memory)',value,0)) memory_sorts,
        sum(decode(c.name,'sorts (rows)',value,0)) rows_sorted,
        round(100 * (sum(decode(c.name,'sorts (disk)',value,0)) /
        'sorts (memory)',value,0)),1,
        sum(decode(c.name,'sorts (memory)',value,0)))),2)
from    sys.v_$sesstat a,
        sys.v_$session b,
        sys.v_$statname c, 
        sys.v_$bgprocess e
where   a.statistic#=c.statistic# and 
        b.sid=a.sid  and 
        e.paddr (+) = b.paddr  and
        c.name in ('sorts (disk)',
                 'sorts (memory)',
                 'sorts (rows)')
group by b.sid, 
         decode (b.username,null,e.name,b.username),
         to_char(logon_time,'dd-mon-yy hh:mi:ss pm') 
order by 5 desc,6 desc  

From the query's output, you can see what sessions may be responsible for disk sort actions.

Finally, to see if any disk sorts are in progress on your database, you can use this query (for Oracle 8.0 and higher) to view the SQL statements causing current disk sorts along with other associated information:

select sql_text,
from   sys.v_$sort_usage a,
       sys.v_$sqlarea b,
       sys.v_$session c
where  a.sqladdr = b.address and
       a.sqlhash = b.hash_value and
       a.session_addr = c.saddr
order by sid

Oracle Archives

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Latest Forum Threads
Oracle Forum
Topic By Replies Updated
Oracle Data Mining: Classification jan.hasller 0 July 5th, 07:19 AM
Find duplicates - Unique IDs Lava 5 July 2nd, 08:30 AM
no matching unique or primary key rcanter 1 April 25th, 12:32 PM
Update values of one table based on condition of values in other table using Trigger Gladiator 3 February 29th, 06:01 PM