Sie sind auf Seite 1von 12

Selecting from the V$SQLAREA View to Find the Worst Queries

SELECTb.usernameusername,
a.disk_readsreads,
a.executionsexec,
a.disk_reads/DECODE(a.executions,0,1,a.executions)
rds_exec_ratio,
a.sql_textstatement
FROMv$sqlareaa,dba_usersb
WHEREa.parsing_user_id=b.user_idANDa.disk_reads>100000
ORDERBYa.disk_readsDESC

The DISK_READS column in the preceding statement can be replaced with the BUFFER_GETS column
to provide information on SQL statements requiring the largest amount of memory.
Now consider the output in a second example where there is a count of a billion-row table
(EMP3) and a count of what was originally a 130M row table (EMP2), where all of the rows in
EMP2, except the first 15 rows inserted, were deleted. Note that Oracle counts all the way
up to the high water mark (HWM) of EMP2 (it read over 800,000, 8K blocks even though all of
the data was only in 1 block). This listing would have told you something is wrong with the
query on EMP2 that needs to be addressed, given that it only has 15 rows in it (analyzing
the table will not improve this).

Selecting from the V$SQL View to Find the Worst Queries


Querying V$SQL allows you to see the shared SQL area statements individually versus grouped
together (as V$SQLAREA does). Here is a faster query to get the top statements from V$SQL
(this query can also access V$SQLAREA by only changing the view name):

SELECT*
FROM(SELECTaddress,
RANK()OVER(ORDERBYbuffer_getsDESC)ASrank_bufgets,
TO_CHAR(100*ratio_to_report(buffer_gets)OVER(),
'999.99')
pct_bufgets
FROMv$sql)
WHERErank_bufgets<11;

AlternativelytogetSQL

/*Formattedon5/22/201311:15:38AM(QP5v5.115.810.9015)*/
SELECT*
FROM(SELECTsql_text,
RANK()OVER(ORDERBYbuffer_getsDESC)ASrank_bufgets,
TO_CHAR(100*ratio_to_report(buffer_gets)OVER(),
'999.99')
pct_bufgets
FROMv$sql)
WHERErank_bufgets<11;

Selecting from V$SESSMETRIC to Find Current Resource-Intensive Sessions


This query shows the sessions that are heaviest in physical reads, CPU usage, or logical
reads over a defined interval (15 seconds, by default). You may want to adjust the
thresholds as appropriate for your environment.

/*Formattedon5/22/201311:23:30AM(QP5v5.115.810.9015)*/
SELECTTO_CHAR(m.end_time,'DDMONYYYYHH24:MI:SS')e_dttm,
m.intsize_csec/100ints,
s.usernameusr,
m.session_idsid,
m.session_serial_numssn,
ROUND(m.cpu)cpu100,
m.physical_readsPrds,
m.logical_readslrds,
m.hard_parseshp,
m.soft_parsessp,
m.physical_read_pctprp,
m.logical_read_pctlrp,
s.sql_id
FROMv$sessmetricm,v$sessions
WHERE(m.physical_reads>100ORm.cpu>100ORm.logical_reads>100)
ANDm.session_id=s.sid
ANDm.session_serial_num=s.serial#
ORDERBYm.physical_readsDESC,m.cpuDESC,m.logical_readsDESC

Selecting from the DBA_HIST_SQLSTAT View to Find the Worst Queries


SQL statements that have exceeded predefined thresholds are kept in the AWR for a predefined
time (seven days, by default). You can query the DBA_HIST_SQLSTAT view to find the worst
queries. The following is the equivalent statement to the V$SQLAREA query earlier in this
chapter.
SELECTsnap_id,
disk_reads_deltareads_delta,
executions_deltaexec_delta,
disk_reads_delta/DECODE(executions_delta,0,1,executions_delta)
rds_exec_ratio,
sql_id
FROMdba_hist_sqlstat
WHEREdisk_reads_delta>10000
ORDERBYdisk_reads_deltaDESC

Note that in the output, the same SQL_ID appears in three different AWR snapshots. (In this
case, it was executed during the first one and is still running). You could also choose to
filter on other criteria, including cumulative or delta values for DISK_READS, BUFFER_GETS,
ROWS_PROCESSED, CPU_TIME, ELAPSED_TIME, IOWAIT, CLWAIT (cluster wait), and so on. Run a DESC
command of the view DBA_HIST_SQLSTAT to get a full list of its columns. This listing shows
different SQL_IDs at the top of the list.

Selecting Query Text from the DBA_HIST_SQLTEXT View


The query text for the offending queries shown in the previous two examples can be obtained
from the DBA_HIST_SQLTEXT view with the following query:

To query DBA_HIST_SQLTEXT:
SELECTcommand_type,sql_text
FROMdba_hist_sqltext
WHEREsql_id='1p5gnckn8s6gv'
Selecting Query EXPLAIN PLAN from the DBA_HIST_SQL_PLAN View
The EXPLAIN PLAN for the offending SQL is also captured. You may view information about the
execution plan through the DBA_HIST_SQL_PLAN view. If you want to display the EXPLAIN PLAN,
the simplest way is to use the DBMS_XPLAN package with a statement such as this one:

select*fromtable(DBMS_XPLAN.DISPLAY_AWR('f3g2hz7dpfy1t'));

SQL> /
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
SQL_ID f3g2hz7dpfy1t
--------------------
DELETE FROM FND_LOG_MESSAGES FLM WHERE FLM.LOG_SEQUENCE=:B1 AND NOT
EXISTS (SELECT NULL FROM FND_LOG_EXCEPTIONS FLE WHERE FLE.LOG_SEQUENCE
= FLM.LOG_SEQUENCE )
Plan hash value: 3090450985
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | | | 4 (100)| |
| 1 | DELETE | FND_LOG_MESSAGES | | | | |
| 2 | NESTED LOOPS ANTI| | 1 | 184 | 4 (0)| 00:00:01 |
| 3 | INDEX RANGE SCAN| FND_LOG_MESSAGES_N5 | 1 | 177 | 4 (0)| 00:00:01 |
| 4 | INDEX RANGE SCAN| FND_LOG_EXCEPTIONS_N3 | 1 | 7 | 0 (0)| |
--------------------------------------------------------------------------------------------

select/*+richs_secret_hint*/ename,jobfromscott.empwheredeptno=10andename='CLARK'

selectename,jobfromscott.empwheredeptno=10andename='CLARK'

createindexdept_idx1onscott.emp(deptno)tablespaceusersstorage(initial20Mnext5M
pctincrease0)

dropindexdept_idx1;

createindexemp_idx1onscott.emp(deptno,ename)tablespaceusersstorage(initial20Mnext
5Mpctincrease0)

select*fromv$sqlwheresql_textlike'%deptno%'andsql_id
in('2v0ntfhzwn2xf','d5thrrkvn8wmu','21rdq0js36ag4','0varr2r8cbt8r')

selectaddressfromv$sqlareawheresql_id
in('2v0ntfhzwn2xf','d5thrrkvn8wmu','21rdq0js36ag4','0varr2r8cbt8r')

ADDRESS

00000001AE820800
00000001AB781740
00000001ADF7AAF0
00000001AE8F6EE8

selectADDRESS,HASH_VALUEfromV$SQLAREAwhereSQL_IDin
('2v0ntfhzwn2xf','d5thrrkvn8wmu','21rdq0js36ag4','0varr2r8cbt8r')

ADDRESSHASH_VALUE
execDBMS_SHARED_POOL.PURGE('00000001AE820800,1070205870','C')

execDBMS_SHARED_POOL.PURGE('00000001AB781740,3074716282','C')

execDBMS_SHARED_POOL.PURGE('00000001ADF7AAF0,1882401252','C')

execDBMS_SHARED_POOL.PURGE('00000001AE8F6EE8,3502630167','C')

selectADDRESS,HASH_VALUEfromV$SQLAREAwhereSQL_IDin
('2v0ntfhzwn2xf','d5thrrkvn8wmu','21rdq0js36ag4','0varr2r8cbt8r')

/*+ result_cache */
To check INACTIVE sessions with HIGH DISK IO
*Formattedon5/23/201312:26:10PM(QP5v5.115.810.9015)*/
SELECTp.spid,
s.username,
s.sid,
s.status,
t.disk_reads,
s.last_call_et/3600last_call_et_Hrs,
s.action,
s.program,
s.machinecli_mach,
s.processcli_process,
LPAD(t.sql_text,30)"LastSQL"
FROMgv$sessions,gv$sqlareat,v$processp
WHEREs.sql_address=t.address
ANDs.sql_hash_value=t.hash_value
ANDp.addr=s.paddr
ANDt.disk_reads>5000
ANDs.status='INACTIVE'
ANDs.process='1234'

To Analyze the DISK I/o's


promptSESSIONSPERFORMINGHIGHI/O>50000

SELECTp.spid,
s.sid,
s.processcli_process,
s.status,
t.disk_reads,
s.last_call_et/3600last_call_et_Hrs,
s.action,
s.program,
LPAD(t.sql_text,30)"LastSQL"
FROMv$sessions,v$sqlareat,v$processp
WHEREs.sql_address=t.address
ANDs.sql_hash_value=t.hash_value
ANDp.addr=s.paddr
ANDt.disk_reads>10000
ORDERBYt.disk_readsDESC;

LATCH Free Sessions Monitoring and Troubleshooting

LATCH COUNT ON DATABASE:


set pagesize 5000
set lines 180
set long 5000
col username for a15
col osuser for a15
col program for a20
col "LOGON_TIME" for a23
col "LAST_CALL_HRS" for 99999.999
col status for a8
col machine for a15
col SQL_TEXT for a90
col P1TEXT for a10
col P2TEXT for a10
col P3TEXT for a10
col p1 for 9999999999999
col p2 for 9999999999999
col p3 for 9999999999999
col event for a50
col "LATCH_NAME" for a20

select event,count(event) "LATCH_COUNT" from v$session_wait having count(event)> 2 and event like '%latch%' group by
event;

LATCH SESSIONS DETAIL:


col event for a10

select s.sid,username,osuser,program,machine,status,to_char(logon_time,'DD-MON-YYYY HH24:MI:SS')


"LOGON_TIME",last_call_et/3600 "LAST_CALL_HRS",sw.event from v$session s,v$session_wait sw where s.sid=sw.sid
and sw.event like '%latch%';

SQL_TEXT OF LATCH SESSIONS:

select s.sid,username,sql_text,sw.event,l.name "LATCH_NAME" from v$session s,v$session_wait sw,v$sqltext sq,v$latch l


where s.sid=sw.sid and sq.address = s.sql_address and l.latch# = sw.p2 and sw.event like '%latch%' order by s.sid,piece;

COMPREHENSIVE
Oracle 11g Automatic SQL Tuning
Oracle Database 10g introduced the SQL Tuning Advisor to help DBAs and developers improve
the performance of SQL statements. The Automatic SQL Tuning Advisor includes statistics
analysis, SQL profiling, access path analysis, and SQL structure analysis, and can be
performed through the SQL Tuning Advisor. The SQL Tuning Advisor uses input from the ADDM,
from resource-intensive SQL statements captured by the AWR, from the cursor cache, or from
SQL Tuning Sets. Oracle 11g has extended the SQL Tuning Advisor by adding additional
features such as SQL Replay, Automatic SQL Tuning, SQL Statistics Management, and SQL Plan
Management. Since this chapter is focused on query tuning, Ill describe how to pass
specific SQL to the SQL Tuning Advisor in the form of a SQL Tuning Set, and then Ill cover
11gs Automatic SQL Tuning Advisor and SQL Performance Analysis (SQL Replay).The Oracle
recommended interface for the SQL Tuning Advisor is Oracle Enterprise Manager (see Chapter
5), but you can use the APIs via the command line in SQL*Plus. I cover the command-line
session so you can better understand the analysis procedure for a single query. This section
is only a small glance into the functionality of the SQL Tuning Advisor. You also have the
capability to create SQL Tuning Sets and SQL profiles as well as the ability to transport
SQL Tuning Sets from one database to another.
Troubleshooting BUFFER BUSY WAITS
Note:
This wait indicates that there are some buffers in the buffer cache that multiple processes
are attempting to access concurrently. Query V$WAITSTAT for the wait statistics for each
class of buffer. Common buffer classes that have buffer busy waits include data block,
segment header, undo header, and undo block.

BUFFER BUSY WAITS COUNT ON DATABASE:

set pagesize 5000


set lines 180
set long 5000
col username for a15
col osuser for a15
col program for a20
col "LOGON_TIME" for a23
col status for a8
col machine for a15
col SQL_TEXT for a90
col EVENT for a50
col P1TEXT for a10
col P2TEXT for a10
col P3TEXT for a10
col p1 for 9999999999999
col p2 for 9999999999999
col p3 for 9999999999999
col "LAST_CALL_HRS" for 99999.999

select event,count(event) "BUFFER_BUSY_WAITS/LOCK_COUNT" from v$session_wait having


count(event)>= 1 and event like '%buffer busy waits%' group by event;

BUFFER_BUSY_WAITS SESSIONS DETAIL:

col event for a10


select s.sid,username,osuser,program,machine,status,to_char(logon_time,'DD-MON-YYYY
HH24:MI:SS') "LOGON_TIME",last_call_et/3600 "LAST_CALL_HRS",sw.event from
v$session s,v$session_wait sw where s.sid=sw.sid and sw.event like '%buffer busy waits%';

SQL_TEXT OF BUFFER_BUSY_WAITS SESSIONS:

col "EVENT" for a25


select s.sid,username "USERNAME",sql_text "SQL_TEXT",sw.event "EVENT" from v$session
s,v$session_wait sw,v$sqltext sq where s.sid=sw.sid and
sq.address = s.sql_address and sw.event like '%buffer busy waits% order by sw.sid,piece';

TYPE_OF_SEGMENT_CONTENDED_FOR

SELECT class, count FROM V$WAITSTAT WHERE count > 0 ORDER BY count DESC;

USE THE BELOW SQL_FILE TO IDENTIFY THE SEGMENT

set linesize 150


set pagesize 5000
col owner for a15
col segment_name for a30
SELECT owner,segment_name,segment_type FROM dba_extents WHERE file_id=&file AND& block_id
BETWEEN block_id AND block_id + blocks -1 ;
Oracle Wait Event Analysis
Wait event
column seq# format 99999
column EVENT format a30
column p2 format 999999
column STATE format a10
column WAIT_T format 9999
select SID,SEQ#,EVENT,P1,P2,WAIT_TIME WAIT_T,SECONDS_IN_WAIT,STATE
from v$session_wait
where sid = '&sid' ;
WAIT EVENT DETAILS COMPLETE

Wait event List in DB

select event,count(event) "EVENT_COUNT" from v$session_wait group by event order by event;


To Find Wait Events for a given Session

column seq# format 99999


column EVENT format a30
column p2 format 9999
column STATE format a10
column WAIT_T format 9999
select SID,SEQ#,EVENT,P1,P2,WAIT_TIME WAIT_T,SECONDS_IN_WAIT,STATE
from gv$session_wait
where sid = '&sid' ;

To Find Wait Event details of a specific wait event

column seq# format 99999


column EVENT format a30
column p2 format 9999
column STATE format a10
column WAIT_T format 9999
select SID,SEQ#,EVENT,P1,P2,WAIT_TIME WAIT_T,SECONDS_IN_WAIT,STATE
from gv$session_wait
where event like '%cursor: pin S%';

Count of sessions ordered by wait event associated

SELECT count(*), event FROM v$session_wait WHERE wait_time = 0 AND event NOT IN ('smon
timer','pmon timer','rdbms ipc message','SQL*Net message from client') GROUP BY event ORDER
BY 1
DESC;

To find Wait event Most of the time the session waited for

select event,TOTAL_WAITS ,TOTAL_TIMEOUTS,TIME_WAITED from gv$session_event where sid=54


order by TIME_WAITED

To find the list of wait events and count of associated sessions

select count(sid),event from v$session_wait group by event order by 1;

No of events with sid's

prompt Sessions Wait Event Summary


select EVENT,COUNT(SID)
from v$session_wait
GROUP BY EVENT;

Obtaining a parameter defined

col value for a10


col description for a30
select name,value,description from v$parameter where name like '%timed_statistics%';

Wait events

set linesize 152


set pagesize 80
column EVENT format a30
select * from v$system_event
where event like '%wait%';

Sessions waiting "sql*net message from client"

prompt Sessions having Wait Event "sql*net message from client"


select program,module,count(s.sid) from v$session s, v$session_Wait w
where w.sid=s.sid and w.event='SQL*Net message from client' group by program,module having
count(s.sid)>5 order by count(s.sid);

Sessions having Wait Event "sql*net message from client" from more than 1Hour

select program,module,count(s.sid) from v$session s, v$session_Wait w


where w.sid=s.sid
and s.last_call_et > 3600
and w.event='SQL*Net message from client' group by program,module having
count(s.sid)>5 order by count(s.sid);

Sessions having Wait Event "sql*net message from client"

select s.sid,s.process,S.STATUS,s.program,s.module,s.sql_hash_value,s.last_call_et/3600
Last_Call_Et_HRS
from v$session s, v$session_Wait w
where w.sid=s.sid and w.event='SQL*Net message from client'
and s.module='&Module_name'
order by 6 desc;

Segment Statistics

select
object_name,
statistic_name,
value
from
V$SEGMENT_STATISTICS
where object_name ='SOURCE$';

select statistic_name, count(object_name) from V$SEGMENT_STATISTICS


where STATISTIC_NAME like 'physical%'
group by statistic_name;

select distinct(STATISTIC_NAME) from v$SEGMENT_STATISTICS;

V$SYSTEM_EVENT

This view contains information on total waits for an event.


Note that the TIME_WAITED and AVERAGE_WAIT columns will contain
a value of zero on those platforms that do not support a fast timing mechanism.
If you are running on one of these platforms and you want this column to reflect
true wait times, you must set TIMED_STATISTICS to TRUE in the parameter file;
doing this will have a small negative effect on system performance.

Buffer Busy waits


SELECT * FROM v$event_name WHERE name = 'buffer busy waits';

SELECT sid, event, state, seconds_in_wait, wait_time, p1, p2, p3


FROM v$session_wait
WHERE event = 'buffer busy waits'
ORDER BY sid;
select * from v$waitstat;

SELECT sid, event, state, seconds_in_wait, wait_time, p1, p2, p3


FROM v$session_wait
WHERE event = 'buffer busy waits'
ORDER BY sid;

Segment details from File number

SELECT owner, segment_name, segment_type


FROM dba_extents
WHERE file_id = &absolute_file_number
AND &block_number BETWEEN block_id AND block_id + blocks -1;

Direct path write

SELECT * FROM v$event_name WHERE name = 'direct path write';

SELECT tablespace_name, file_id "AFN", relative_fno "RFN"


FROM dba_data_files
WHERE file_id = 201;
SELECT tablespace_name, file_id "AFN", relative_fno "RFN"
FROM dba_data_files
WHERE file_id = 201;

Total waits/time waited/max wait for a session

SELECT event, total_waits, time_waited, max_wait


FROM v$session_event
WHERE sid = 47
ORDER BY event;

SELECT A.name, B.value


FROM v$statname A, v$sesstat B
WHERE A.statistic# = 12
AND B.statistic# = A.statistic#
AND B.sid = 47;
Sessions Ordered by Wait event in Database

set lines 150


set pages 500
col event for a50
select event,count(event) "EVENT_COUNT" from v$session_event group by event order by event;
DB File Scattered read Monitoring and Troubleshooting

Note:
This event signifies that the user process is reading buffers into the SGA buffer cache and is waiting for a physical I/O call to
return. A db file scattered read issues a scatter-read to read the data into multiple discontinuous memory locations. A
scattered read is usually a multiblock read. It can occur for a fast full scan (of an index) in addition to a full table scan.

The db file scattered read wait event identifies that a full table scan is occurring. When performing a full table scan into the
buffer cache, the blocks read are read into memory locations that are not physically adjacent to each other. Such reads are
called scattered read calls, because the blocks are scattered throughout memory. This is why the corresponding wait event is
called 'db file scattered read'. Multiblock (up to DB_FILE_MULTIBLOCK_READ_COUNT blocks) reads due to full table scans
into the buffer cache show up as waits for 'db file scattered read'.

DB_FILE_SCATTERED_READ COUNT ON DATABASE:

set pagesize 5000


set lines 185
set long 5000
col username for a15
col osuser for a15
col program for a20
col "LOGON_TIME" for a23
col status for a8
col machine for a15
col SQL_TEXT for a90
col EVENT for a50
col P1TEXT for a10
col P2TEXT for a10
col P3TEXT for a10
col p1 for 9999999999999
col p2 for 9999999999999
col p3 for 9999999999999
col "LAST_CALL_HRS" for 99999.999
col STATE for a12
select event,count(event) "DB_FILE_SCATTERED_READ_COUNT" from v$session_wait having count(event)>= 1 and event
like '%scattered%' group by event;
DB_FILE_SCATTERED_READ SESSIONS DETAIL:
col event for a25
select s.sid,username,osuser,program,machine,status,to_char(logon_time,'DD-MON-YYYY HH24:MI:SS')
"LOGON_TIME",last_call_et/3600 "LAST_CALL_HRS",sw.event from
v$session s,v$session_wait sw where s.sid=sw.sid and sw.event like '%scattered%';

DB_FILE_SCATTERED_READ_WAIT_DETAIL:

select sid,EVENT,P1TEXT,P1,P2TEXT,P2,P3TEXT,P3,WAIT_TIME,SECONDS_IN_WAIT,STATE from v$session_wait where


event like '%scattered%';

SQL_TEXT OF DB_FILE_SCATTERED_READ SESSIONS:

select sw.sid,username,sql_text "SQL_TEXT",sw.event from v$session s,v$session_wait sw,v$sqltext sq where s.sid=sw.sid


and sq.address = s.sql_address and sw.event like '%scattered%' order by sw.sid,piece;

USE THE BELOW SQL_FILE TO IDENTIFY THE SEGMENT:

set linesize 150


set pagesize 5000
col owner for a15
col segment_name for a30
SELECT owner,segment_name,segment_type FROM dba_extents WHERE file_id=&file AND &block_id BETWEEN block_id
AND block_id + blocks -1 ;
LATCH Free Sessions Monitoring and Troubleshooting

LATCH COUNT ON DATABASE:


set pagesize 5000
set lines 180
set long 5000
col username for a15
col osuser for a15
col program for a20
col "LOGON_TIME" for a23
col "LAST_CALL_HRS" for 99999.999
col status for a8
col machine for a15
col SQL_TEXT for a90
col P1TEXT for a10
col P2TEXT for a10
col P3TEXT for a10
col p1 for 9999999999999
col p2 for 9999999999999
col p3 for 9999999999999
col event for a50
col "LATCH_NAME" for a20

select event,count(event) "LATCH_COUNT" from v$session_wait having count(event)> 2 and event like '%latch%' group by
event;

LATCH SESSIONS DETAIL:


col event for a10

select s.sid,username,osuser,program,machine,status,to_char(logon_time,'DD-MON-YYYY HH24:MI:SS')


"LOGON_TIME",last_call_et/3600 "LAST_CALL_HRS",sw.event from v$session s,v$session_wait sw where s.sid=sw.sid
and sw.event like '%latch%';

SQL_TEXT OF LATCH SESSIONS:

select s.sid,username,sql_text,sw.event,l.name "LATCH_NAME" from v$session s,v$session_wait sw,v$sqltext sq,v$latch l


where s.sid=sw.sid and sq.address = s.sql_address and l.latch# = sw.p2 and sw.event like '%latch%' order by s.sid,piece;

To check number of CPU's in the server


Linux
cat /proc/cpuinfo | grep "processor"|wc l

To identify High Disk I/o using Unix command


/usr/bin/ps -eo pid,user,pcpu,args | grep -v %CPU | sort -nbk 3 | tail -25

Das könnte Ihnen auch gefallen