Thursday, June 1, 2017

Frequently Used Tables Query

Frequently Used Tables Query


We can find out which tables and indexes are in use through two different mechanisms.

V$SEGMENT_STATISTICS

Of course Oracle tracks the tables in use. In this case, we can see this information in the view V$SEGMENT_STATISTICS. This view contains a lot of information about any all of the different segments in your Oracle database. A [segment][seg] is the set of extents (data blocks) allocated to a single database object. The V$SEGMENT_STATISTICS view needs to be pivoted to get the information we need – it contains one row for reads, one for writes, etc.

This basic query will let us see the volume of activity on different segments in the database:

SELECT  vss.owner,
        vss.object_name,
        vss.subobject_name,
        vss.object_type ,
        vss.tablespace_name ,
        SUM(CASE statistic_name WHEN 'logical reads' THEN value ELSE 0 END
            + CASE statistic_name WHEN 'physical reads' THEN value ELSE 0 END) AS reads ,
        SUM(CASE statistic_name WHEN 'logical reads' THEN value ELSE 0 END) AS logical_reads ,
        SUM(CASE statistic_name WHEN 'physical reads' THEN value ELSE 0 END) AS physical_reads ,
        SUM(CASE statistic_name WHEN 'segment scans' THEN value ELSE 0 END) AS segment_scans ,
        SUM(CASE statistic_name WHEN 'physical writes' THEN value ELSE 0 END) AS writes
FROM    v$segment_statistics vss
WHERE   vss.owner NOT IN ('SYS', 'SYSTEM')
GROUP BY vss.owner,
        vss.object_name ,
        vss.object_type ,
        vss.subobject_name ,
        vss.tablespace_name
ORDER BY reads DESC;

This approach will show us information about reads, writes, and segment scans (full table scans) since the dynamic view was last cleared. Typically, this is going to show us information since the database was last started.

The downside of V$SEGMENT_STATISTICS is that it’s across the lifetime of that process. If you happen to have great database up time, a table or index could show up in V$SEGMENT_STATISTICS even though it hasn’t been used in weeks or months.

QUERY WAITS

In order to determine which queries are hitting which tables, we can start sampling the current waits in the system. V$SESSION_WAIT contains a bunch of information including the cryptic p1, p2, and p3 columns. For disk related waits, we only need the p1 and p2 waits. These refer to the file and block number that are a part of the wait. To see what’s going on, we can just do something like:

SELECT  vs.username ,
        vsw.wait_class,
        vsw.EVENT AS wait_type ,
        vsw.WAIT_TIME_MICRO / 1000 AS wait_time_ms ,
        vsw.TIME_REMAINING_MICRO / 1000 AS time_remaining_ms ,
        vsw.STATE ,
        de.SEGMENT_NAME ,
        de.SEGMENT_TYPE,
        de.OWNER ,
        de.TABLESPACE_NAME
FROM    V$SESSION_WAIT vsw
        JOIN V$SESSION vs ON vsw.SID = vs.SID
        LEFT JOIN DBA_EXTENTS de ON vsw.p1 = de.file_id
                                    AND vsw.p2 BETWEEN de.BLOCK_ID AND (de.BLOCK_ID + de.BLOCKS)
WHERE   vsw.wait_class <> 'Idle'
        AND vs.username IS NOT NULL
ORDER BY wait_time_ms DESC;


This query will show us:

Who’s running a query
What their current wait is
If it’s a disk wait, which tablespace, object, and object type is being waited on.
The problem with this approach, though, is that it will only catch the queries that are running at the moment you sample. With enough samples, this can be effective, but sampling the system is going to put a small load on it.

ACTIVE SESSION HISTORY

If you’re licensed for the Oracle Diagnostic Pack, you’ll have access to the Active Session History. If you aren’t licensed for the Diagnostic Pack, keep reading, but don’t run these queries on any of your Oracle systems – your Oracle auditors will love you, but your accountants won’t.

Active Session History samples data over time and lets us know which queries have been running inside a given time window. The upside of this is that we can dig into the data collected and figure out if the tables we’re interested in have been used inside a given time window.


SELECT  du.username,
        s.sql_text,
        MAX(ash.sample_time) AS last_access ,
        sp.object_owner ,
        sp.object_name ,
        sp.object_alias as aliased_as ,
        sp.object_type ,
        COUNT(*) AS access_count
FROM    v$active_session_history ash
        JOIN v$sql s ON ash.force_matching_signature = s.force_matching_signature
        LEFT JOIN v$sql_plan sp ON s.sql_id = sp.sql_id
        JOIN DBA_USERS du ON ash.user_id = du.USER_ID
WHERE   ash.session_type = 'FOREGROUND'
        AND ash.SQL_ID IS NOT NULL
        AND sp.object_name IS NOT NULL
        AND ash.user_id <> 0
GROUP BY du.username,
        s.sql_text,
        sp.object_owner,
        sp.object_name,
        sp.object_alias,
        sp.object_type
ORDER BY 3 DESC;

You can use this query as a basis to help you isolate who is using which tables and how frequently the queries are being run. If you’re looking for one particular table or index, you can start filtering through the query plan operations to find the object in question.

THREE WAYS TO FIND THE TRUTH

So, there you have it – three ways to find some version of the truth. Looking at V$SEGMENT_STATISTICS will let you understand the way tables have been used historically, but it won’t help you understand if a table has been used recently. V$SESSION_WAIT can be sampled to get a better idea of which tables and indexes are being used and who is using them. And if you need an accurate view, and you’re licensed for the Diagnostic Pack, you can use V$ACTIVE_SESSION_HISTORY to review how frequently a table or index has been used over time.

Identifying Which Session To Terminate

Identifying Which Session To Terminate


To identify the system identifier (SID) and serial number of a session, query the V$SESSION dynamic performance view

SELECT SID, SERIAL#, STATUS FROM V$SESSION WHERE USERNAME = 'M.QADER';

SID SERIAL# STATUS
----- --------- --------
2 13 ACTIVE
4 23 INACTIVE

A session is ACTIVE when it is making a SQL call to Oracle Database.

ALTER SYSTEM KILL SESSION '4,23';

To Check Locked Objects In Applications

To Check Locked Objects In Applications


 SELECT distinct 'alter system kill session'''||vs.sid||','||vs.serial#||''';'
       ,vs.USERNAME
       ,fu.user_name
       ,ACTION
FROM fnd_logins fl
,fnd_user fu
,v$locked_object vlocked
,v$process vp
,v$session vs
,dba_objects c
WHERE vs.sid   = vlocked.session_id
AND vlocked.object_id = c.object_id
AND vs.paddr   = vp.addr
AND vp.spid    = fl.process_spid(+)
AND vp.pid     = fl.pid(+)
AND fl.user_id = fu.user_id(+);

Troubleshoot Long Running Concurrent Request In Apps 11i/R12

Troubleshoot Long Running Concurrent Request In Apps 11i/R12



Step 1 : Check Concurrent Request ID of long running concurrent request from front end

Step 2 : Find SID, SERIAL# and SPID by running SQL (given below)

Step 3 : Enable event 10046 trace with level 12 using oradebug ( for 15-20 minute)

Step 4 : Disable trace (once you are happy with trace size)

Step 5 : Convert raw trace to TKPROF using various sort options like fchela, prsela, execpu

Step 6 : Check TKPROF out file to find root cause of slow concurrent request


In Detail:


Step 1 : Check Request ID from Find Concurrent request screen
system administrator--> concurrent request --> select phase=Running and status=Normal
uncheck on long running request

(In my case Request ID is 31487467) when prompted

SELECT a.request_id, d.sid, d.serial# ,d.osuser,d.process , c.SPID FROM apps.fnd_concurrent_requests a,
apps.fnd_concurrent_processes b, v$process c, v$session d WHERE a.controlling_manager = b.concurrent_process_id
AND c.pid = b.oracle_process_id AND b.session_id=d.audsid AND a.request_id = &Request_ID;


O/P:

REQUEST_ID    SID    SERIAL#    OSUSER    PROCESS    SPID   

31487467           249     47495             oracle       12922           20732


Step 3.1 : Check and confirm SPID on Database Node

oracle@testdb trace]$ ps -ef|grep 20732
oracle   20732     1 14 16:03 ?        00:09:29 oracleJUNCLN (LOCAL=NO)
oracle   23967  9608  0 17:10 pts/2    00:00:00 grep 20732


Step 3.2 : Set OSPID (20732 in my case) for ORADEBUG


SQL> oradebug setospid 20732

Oracle pid: 58, Unix process pid: 20732, image: oracle@testdb.sapac.com.sa

SQL> oradebug event 10046 trace name context forever, level 12
Statement processed.

LEVEL 12 – Both Binds and Waits
LEVEL 8 – Only WAITS
LEVEL 4 – Only BIND Variables

Step 3.4 : Locate Trace file as

SQL> oradebug tracefile_name

/u01/oracle/JUNCLN/db/tech_st/11.1.0/admin/JUNCLN_testdb/diag/rdbms/juncln/JUNCLN/trace/JUNCLN_ora_20732.trc

Wait for 15-20 minutes


Step 4 : Disable trace

SQL> oradebug event 10046 trace name context off


Step 5: Create tkprof file like


[oracle@testdb trace]$ tkprof JUNCLN_ora_20732.trc JUNCLN_ora_20732_txt explain=apps/******* sort=(exeela,fchela) sys=no


Step 6 : Check TKPROF file to find root cause of slow concurrent request


Session Details Queries

Session Details Queries

### session by cpu-usage:


SELECT ss.username, se.SID, VALUE / 100 cpu_usage_seconds
FROM v$session ss, v$sesstat se, v$statname sn
WHERE     se.STATISTIC# = sn.STATISTIC#
     AND NAME LIKE '%CPU used by this session%'
     AND se.SID = ss.SID
     AND ss.status = 'ACTIVE'
     AND ss.username IS NOT NULL
ORDER BY VALUE DESC;

### session sorted by logon time:

select  username
 , osuser
 , sid || ',' || serial# "ID"
 , status
 , to_char(logon_time, 'hh24:mi dd/mm/yy') login_time
 , last_call_et
 from v$session
 where username is not null
 order by login_time;



Top SQL's In Database

Top SQL's In Database


 SELECT *
  FROM (  SELECT username,
                 LAST_LOAD_TIME,
                 sql_text,
                 sql_id,
                 elapsed_time,
                 cpu_time,
                 user_io_wait_time
            FROM sys.v_$sqlarea s, dba_users u
           WHERE     u.USER_ID = s.PARSING_USER_ID
                 AND TRUNC (LAST_LOAD_TIME) = TRUNC (SYSDATE)
                 AND u.username =user
        ORDER BY 6 DESC)
 WHERE ROWNUM < 10;