Question

I need to do a query on the v$session_wait looking for events, I need to get the events with certain max values: For example:

db file scattered read > 20 
db file sequential read > 25 
buffer busy   waits > 30 
SQL*Net message from dblink > 20 
log file sync > 10

And I have this query:

SELECT COUNT(*), event
FROM v$session_wait
WHERE event NOT IN ('pipe get','PL/SQL lock timer','SQL*Net more data from
client','queue messages','SQL*Net message from client','pmon timer','rdbms ipc 
message','SQL*Net message to client','smon timer','wakeup time manager','virtual 
circuit status','wait for unread message on broadcast channel','jobq slave wait')
AND event NOT LIKE 'Streams%AQ%'
GROUP BY event
HAVING COUNT('db file scattered read')  >= 4 
OR COUNT('db file sequential read')     >= 4 
OR COUNT('buffer busy waits')           >= 7 
OR COUNT('latch free%')                 >= 1 
OR COUNT('library cache%')              >= 8 
OR COUNT('enqueue')                     >= 8 
OR COUNT('read by other session')       >= 8 
OR COUNT('log file sync')               >= 2 
OR COUNT('SQL*Net message from dblink') >= 2 
;

But the results are not what I want.

I need to group each event and result with the max value above.

Any help?

Was it helpful?

Solution

The HAVING Clause is wrong in this situation. You could rewrite that like this:

SELECT event,cnt 
FROM (
    SELECT COUNT(*) as cnt, event
    FROM v$session_wait
    WHERE event NOT IN (
        'pipe get', 'PL/SQL lock timer', 'SQL*Net more data from client', 
        'queue messages', 'SQL*Net message from client', 'pmon timer', 
        'rdbms ipc message', 'SQL*Net message to client', 'smon timer', 
        'wakeup time manager', 'virtual  circuit status', 
        'wait for unread message on broadcast channel', 'jobq slave wait'
        )
      AND event NOT LIKE 'Streams%AQ%'
    GROUP BY event
) a
WHERE (CASE WHEN event = 'db file scattered read' AND cnt >= 4 THEN 1
        WHEN event = 'db file sequential read' AND cnt >= 4 THEN 1
        WHEN event = 'buffer busy waits' AND cnt >= 7 THEN 1
        WHEN event = 'latch free%' AND cnt >= 1 THEN 1
        WHEN event = 'library cache%' AND cnt >= 8 THEN 1
        WHEN event = 'enqueue' AND cnt >= 8 THEN 1
        WHEN event = 'read by other session' AND cnt >= 8 THEN 1
        WHEN event = 'log file sync' AND cnt >= 2 THEN 1
        WHEN event = 'SQL*Net message from dblink' AND cnt >= 2 THEN 1
        ELSE 0 END) = 1

But if you want the row that has MAX for COUNT on the inner query, you can just do:

SELECT event,cnt 
FROM (
    SELECT COUNT(*) as cnt, event
    FROM v$session_wait
    WHERE event NOT IN (
        'pipe get', 'PL/SQL lock timer', 'SQL*Net more data from client', 
        'queue messages', 'SQL*Net message from client', 'pmon timer', 
        'rdbms ipc message', 'SQL*Net message to client', 'smon timer', 
        'wakeup time manager', 'virtual  circuit status', 
        'wait for unread message on broadcast channel', 'jobq slave wait'
        )
    AND event NOT LIKE 'Streams%AQ%'
    GROUP BY event
    ORDER BY COUNT(*) DESC
) a
WHERE ROWNUM = 1
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top