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?

Était-ce utile?

La 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top