Tuesday, July 19, 2022

Step by Step: How to troubleshoot a slow running query in Oracle

This is a day to day task of a DBA. Someone from application team comes to our desk and simply says a query is running slow. We may question him on many things but ultimately a DBA has to tune the query at the end.

This is also very popular and known question for the DBA's who are attending interviews. This question is simply asked again and again. I have also been asked this question multiple times. After a pause, interviewer simply asks...so suppose a user comes and reports that his query is running slow, what will be your approach to tune this.

There is no absolute or concrete answer to this question because there might be multiple way to tune a slow running query. Everyone can have a different approach.

So here is my approach:

Very first thing we have to find which type of query is running slow. Whether it is SELECT query of DML statements(insert, update, delete and merge).

So first we will see how to tune a SELECT query

Step 1 – Find the SQL_ID of the slow running query

There could be two possibilities:

 1) Query is still running: If the slow query is still running then we can find the sql_id of the query by using v$session view.

SQL>select sql_id
from v$session
where sid = 509;
Output:
SQL_ID
—————————————————
5mb06b73785kd

2)  Query is completed: It might be query is completed but application team got to know it later that the query was slow and it did not finish in its usual time. Since this query is not running right now, we can’t query v$session to get its information.

So for this we use AWR/ASH report. We ask application team that at what time the query was running and for that duration we generate the AWR. In ASH report we find all kind of information regarding the top SQL’s. Basically we see SQL STATISTIS section of the AWR report. In this section there is SQL ORDERED BY ELAPSED TIME which matters most to us. If the query which is reported by application team is present in this section then we note down the sql_id of the query. Otherwise we generate ASH report for that particular time and get the sql_id.
  
Step 2 – Run the SQL Tuning advisor for that SQL_ID

After finding the sql_id we can run sql tuning advisor on this sql_id.
Use below steps to run the sql tuning advisor and display its output:

1. Create tuning task for specific Sql id:

SET SERVEROUTPUT ON
DECLARE
  l_sql_tune_task_id  VARCHAR2(100);
BEGIN
  l_sql_tune_task_id := DBMS_SQLTUNE.create_tuning_task (
                          sql_id      => '5mb06b73785kd',
                          scope       => DBMS_SQLTUNE.scope_comprehensive,
                          time_limit  => 60,
                          task_name   => '5mb06b73785kd_tuning_task',
                          description => 'Tuning task for statement 5mb06b73785kd.');
  DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id);
END;
/

2. Execute the tuning task:

EXEC DBMS_SQLTUNE.execute_tuning_task(task_name => '5mb06b73785kd_tuning_task');


3. Display the recommendations:

Once the tuning task has executed successfully the recommendations can be displayed using the REPORT_TUNING_TASK function.

SET LONG 10000;
SET PAGESIZE 1000
SET LINESIZE 200

SELECT DBMS_SQLTUNE.report_tuning_task('5mb06b73785kd_tuning_task') AS recommendations FROM dual;

SET PAGESIZE 24


Based on the tuning advisor recommendation we have to take corrective actions. These recommendation could be and many more:

1) Gather Statistics
2) Create Index
3) Drop Index
4) Join orders
5) Accept sql profile
6) Create baseline and many more recommnendations

Before applying any corrective action on production, we need to test that in DEV/QA/UAT/TEST environment or we can ask an tuning expert that this is the recommendation. After all the analysis we should apply in the production database.

After corrective action from tuning advisor run the SQL again and see the improvement.

Step 3 - Check the sql plan hash value and pin the good plan:

Sometime SQL tuning advisor does not recommend anything, in that case we have to go for a different approach.

check if there is any change in the sql plan.

set lines 500
set pages 500
col Snap for a25
col SQL_PROFILE for a40
select distinct b.BEGIN_INTERVAL_TIME as Snap, a.PLAN_HASH_VALUE as plan, a.EXECUTIONS_DELTA as EXECUTIONS, a.ELAPSED_TIME_DELTA/1000000 as ELAPSED_SEC, ROWS_PROCESSED_DELTA as "ROWS" , a.ROWS_PROCESSED_DELTA/CASE WHEN a.EXECUTION_DELTA = 0 THEN -1 ELSE a.EXECUTIONS_DELTA END "Avg Rows", a.ELAPSED_TIME_DELTA/1000000/CASE WHEN a. EXECUTION_DELTA = 0 THEN -1 ELSE a.EXECUTION_DELTA END "Avg Elapsed", a.optimizer_cost, a.SQL_PROFILE from DBA_HIST_SQLSTAT a, DBA_HIST_SNAPHOT b where a.SQL_ID = '&sqlid' and a.snap_id = b.snap_id order by b.BEGIN_INTERVAL_TIME

We can also use below query to to find out the sql plan for n number of days:
(Show the plan has value for a given sqlid over a given period)

SET PAUSE ON
SET PAUSE 'Press Return to Continue'
SET PAGESIZE 60
SET LINESIZE 300

SELECT DISTINCT sql_id, plan_hash_value
FROM dba_hist_sqlstat q,
    (
    SELECT /*+ NO_MERGE */ MIN(snap_id) min_snap, MAX(snap_id) max_snap
    FROM dba_hist_snapshot ss
    WHERE ss.begin_interval_time BETWEEN (SYSDATE - &No_Days) AND SYSDATE
    ) s
WHERE q.snap_id BETWEEN s.min_snap AND s.max_snap
  AND q.sql_id IN ( '&SQLID')
/

here we have to supply the value for number of days.

We can see the entire plan for n number of days the query has used. It is not mandatory that plan is changed. Here it also displays which plan takes how much time executes. So if there is change in plan, we should find best plan and pin it. Plan could be changed due to several reasons like change in the sql, due to stats gathering and many more.

Step 4 - Use TOP command to check the CPU usages by various processes:

TOP command is also useful for performance tuning. Many times, in a single server multiple databases are running. It may happen that one database is consuming more server resources than others. So we have to find out which oracle process is consuming more resources and it is related to which database. For this we use  TOP command. If we see there is CPU used by an oracle process is very high then this a matter of subject to worry about.

$top

Output of the top command 
top - 10:56:49 up 18 days, 18:48,  4 users,  load average: 1.02, 0.92, 0.48
Tasks: 180 total,   2 running, 178 sleeping,   0 stopped,   0 zombie
Cpu(s): 49.8%us,  0.5%sy,  0.0%ni, 49.2%id,  0.5%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1815256k total,  1771772k used,    43484k free,    66120k buffers
Swap:  2031608k total,   734380k used,  1297228k free,   747740k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 5946 oracle    25   0  706m 177m 159m R  100 10.0   9:20.26 oracle
 6104 oracle    15   0  2324 1060  800 R    1  0.1   0:00.12 top
31446 oracle    15   0  688m 135m 129m S    0  7.7   0:08.24 oracle
… output truncated …

In the output, we can see that the process with ID 5946 consumes the most CPU (100 percent) and memory (10 percent) and therefore should be the focus of our attention. To find out more about the process, enter the following command at the UNIX prompt: 
$ ps -aef|grep 5946

oracle    5946  5945 63 10:59 ?
00:01:52 oracleD112D2 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))

The output shows the entire description of the process, which is clearly an Oracle “server process”—a process that is created by Oracle Database when a session is established—and that the process has been running for 1 minute and 52 seconds. The next question, then, is which Oracle Database session this process was created for. For that, we should look into another view—V$PROCESS—where the SPID column shows the server process ID. However, this view does not show the session information, so we need to join this view with the familiar V$SESSION view, as follows: 
select sid
from v$session s, v$process p
where p.spid = 5946
and s.paddr = p.addr;

SID
———
37

Once we know the SID, we can get everything we need to know about the session—the user who established the session, the machine it came from, the operating system user, the SQL it is executing, and so on—from the V$SESSION view. To find the SQL being run by session 37, use this query: 
select sql_fulltext
from v$sql l, v$session s
where s.sid = 37
and l.sql_id = s.sql_id;

Here is the output: 
select max(test1.owner)
from test1, test2, test2, test2,
     test2, test2, test2, test2,
     test2, test2, test2, test2,
     test2, test2, test2, test2,
     test2, test2, test2, test2,
     test2, test2, test2, test2;

This SQL is performing multiple Cartesian joins, so it’s no wonder it’s consuming so much CPU and memory. 
Since this session is using most of the CPU, other sessions on the database might be waiting for the CPU to get their job done. But until or unless this session releases the CPU others won't be able to complete their job. So we can kill this high CPU consuming session so that others can complete their execution. And later on we can investigate why this is consuming so much of CPU.

If it is a DML statement then we have check the locking in the database

Step 5 - Find the locking in the database:

The very first step is to find out if there is any locking in the database. Sometime due to locking a session does not get the required resources and the session gets slow.

We can find below command to check locking in the database:

In Standalone:

sql>select s1.username || '@' || s1.machine || ' ( SID=' || s1.sid || ') is blocking'
       || s2.username || '@' || s2.machine || '( SID=' || s2.sid || ')' from
       v$lock l1, v$session s1, v$lock l2, v$session s2
       where s1.sid=l1.sid and s2.sid=l2.sid
       and l1.block=1 and l2.request > 0
       and l1.id1=l2.id1
       and l2.id2=l2.id2;

In RAC:

sql> select s1.username || '@' || s1.machine || ' ( SID=' || s1.sid || ') is blocking'
        || s2.username || '@' || s2.machine || '( SID=' || s2.sid || ')' from
       gv$lock l1, gv$session s1, gv$lock l2, gv$session s2
       where s1.sid=l1.sid and s2.sid=l2.sid
       and l1.block=1 and l2.request > 0
       and l1.id1=l2.id1
       and l2.id2=l2.id2;


Query Output:

S1.USERNAME||'@'||S1.MACHINE||'(SID='||S1.SID||')ISBLOCKING'||S2.USERNAME||'@'||
----------------------------------------------------------------------------------------
SYS@host1.abc.com ( SID=229) is blockingSYS@host1.abc.com( SID=226)

If we see the locking from above query then we can simply inform to user/application. And if they suggest to kill this blocking session then after killing we can get rid of this slowness.


Step 6 - Check for the wait events:

There could be some wait events on the database. Check for the particular user and session.

Query for displaying sessions, session state, and wait details

col "Description" format a50
select sid,
        decode(state, 'WAITING','Waiting',
                'Working') state,
        decode(state,
                'WAITING',
                'So far '||seconds_in_wait,
                'Last waited '||
                wait_time/100)||
        ' secs for '||event
        "Description"
from v$session
where username = 'ARUP';

Output:

SID   STATE       Description
————— ——————————  ———————————————————————————————————————————————————————
2832  Working     Last waited 2029 secs for SQL*Net message from client
3346  Waiting     So far 743 secs for enq: TX - row lock contention
4208  Waiting     So far 5498 secs for SQL*Net message from client

It clearly shows the state of the sessions: whether they are working or waiting; if they are working, what they were waiting for earlier and for how long; and if they are waiting, what for and for how long.

In many troubleshooting situations, just knowing the SID of each session is not enough. We may need to know other details, such as the client machine the session is connecting from, the user (of both the database and the operating system), and the service name. All of this information is also readily available in the same V$SESSION view we have been using. Let’s briefly examine the columns that provide that information, by running the below query

select SID, osuser, machine, terminal, service_name,
       logon_time, last_call_et
from v$session
where username = 'ARUP';

SID   OSUSER  MACHINE   TERMINAL  SERVICE_NAME  LOGON_TIME LAST_CALL_ET
————— ——————  ———————   ————————  ————————————  —————————— ————————————
3346  oradb   prodb1    pts/5     SYS$USERS     05-FEB-12          6848
2832  oradb   prodb1    pts/6     SERV1         05-FEB-12          7616
4408  ANANDA  ANLAP     ANLAP     ADHOC         05-FEB-12             0

OSUSER. The operating system user as which the client is connected. The output indicates that session 4408 is connected from the ANLAP machine, where a Windows user, ANANDA, has logged in.
MACHINE. The name of the machine where the client is running. This could be the database server itself. For two of the sessions, the machine name shows up as “prodb1.” Session 4408 runs on a different machine—ANLAP—presumably a laptop.
TERMINAL. If the session is connected from a UNIX server, this is the terminal where it runs.
LOGON_TIME. This shows when the session was first connected to the Oracle Database instance.
Using the columns shown in Listing 5, you can get very detailed information on a user’s sessions.
Suppose you receive a complaint that the applications running on the application server named appsvr1 are experiencing performance issues. Listing 6 shows a query against the V$SESSION view—including columns you’ve used in previous queries in this article—for the sessions connected from that machine and the output.
Code Listing 6: Session waits for a specific machine

col username format a5
col program format a10
col state format a10
col last_call_et head 'Called|secs ago' format 999999
col seconds_in_wait head 'Waiting|for secs' format 999999
col event format a50
select sid, username, program,
        decode(state, 'WAITING', 'Waiting',
                'Working') state,
last_call_et, seconds_in_wait, event
from v$session
where machine = 'appsvr1'
/
                                       Called      Waiting
SID   USERNAME  PROGRAM       STATE    secs ago    for secs   EVENT
————— ———————   ———————————   ———————  —————————   ————————   ——————————————————
2832  ARUP      sqlplus.exe   Waiting       152         151   SQL*Net message
                                                              from client
3089  ARUP      sqlplus.exe   Waiting       146         146   enq: TX - row lock
                                                              contention
3346  ARUP      sqlplus.exe   Working        18          49   SQL*Net message
                                                              from clie
History of wait events in a specific session 

set lines 120 trimspool on
col event head "Waited for" format a30
col total_waits head "Total|Waits" format 999,999
col tw_ms head "Waited|for (ms)" format 999,999.99
col aw_ms head "Average|Wait (ms)" format 999,999.99
col mw_ms head "Max|Wait (ms)" format 999,999.99
select event, total_waits, time_waited*10 tw_ms,
       average_wait*10 aw_ms, max_wait*10 mw_ms
from v$session_event
where sid = 37
/


                                  Total      Waited     Average         Max
Waited for                        Waits    for (ms)   Wait (ms)   Wait (ms)
—————————————————————————— ————————————  ———————————  ——————————  —————————
Disk file operations I/O              8         .00         .10         .00
KSV master wait                       2      350.00      173.20      340.00
os thread startup                     1       20.00       19.30       20.00
db file sequential read               5      160.00       32.10       70.00
direct path read                  1,521   51,010.00       33.50      120.00
direct path read temp           463,035  513,810.00        1.10      120.00
direct path write temp               20      370.00       18.70       50.00
resmgr:cpu quantum                   21      520.00       24.60      110.00
utl_file I/O                          8         .00         .00         .00
SQL*Net message to client            20         .00         .00         .00
SQL*Net message from client          20    9,620.00      481.20    9,619.00
kfk: async disk IO              904,818    3,050.00         .00         .00
events in waitclass Other            35       20.00         .70       20.00


Step 7 - Getting the SQL:

Another key piece of performance tuning information is the SQL statement a session is executing, which will provide more insights into the workings of the session. The same V$SESSION view also shows the SQL statement information. The SQL_ID column in the V$SESSION view shows the ID of the last SQL statement executed. W can get the text of that SQL statement from the V$SQL view, using the SQL_ID value. Here is an example of how I have identified the SQL statement executed by the session that appears slow to the user.

select sql_id
from v$session
where sid = 3089;

SQL_ID
—————————————————
g0uubmuvk4uax

set long 99999
select sql_fulltext
from v$sql
where sql_id = 'g0uubmuvk4uax';
SQL_FULLTEXT
————————————————————————————————————————
update t1 set col2 = 'y' where col1 = 1

Step 8 - Data Access issue:

Although locking-related contention is a very common cause, it is not the only cause of performance problems. Another major cause of contention is disk I/O. When a session retrieves data from the database data files on disk to the buffer cache, it has to wait until the disk sends the data. This wait shows up for that session as “db file sequential read” (for index scans) or “db file scattered read” (for full-table scans) in the EVENT column, as shown below:

select event
from v$session
where sid = 3011;

EVENT
—————————————————————————
db file sequential read

When we see this event, we know that the session is waiting for I/O from the disk to complete. To make the session go faster, we have to reduce that waiting period. There are several ways to reduce the wait:

Reduce the number of blocks retrieved by the SQL statement. Examine the SQL statement to see if it is doing a full-table scan when it should be using an index, if it is using a wrong index, or if it can be rewritten to reduce the amount of data it retrieves.

 Place the tables used in the SQL statement on a faster part of the disk. 

Consider increasing the buffer cache to see if the expanded size will accommodate the additional blocks, therefore reducing the I/O and the wait.  

 Tune the I/O subsystem to return data faster.

To find the table causing a wait, we will again use the V$SESSION view. The view’s P1 and P2 columns provide information about the segment the session is waiting for. Below shows a query of P1 and P2, and the output.There are other options as well, but the preceding ones are the most common remediation techniques. The exact activity we undertake depends on our specific situation, but the first technique—reducing the number of blocks retrieved by a SQL statement—almost always works.  When we think about tuning to reduce the number of blocks, we can look at the SQL statement to see which table is being selected from. But what if you see two or more tables in the statement? How do we determine which table is causing the wait?

To find the table causing a wait, we will again use the V$SESSION view. The view’s P1 and P2 columns provide information about the segment the session is waiting for. below query shows a query of P1 and P2, and the output.

Query to  Check data access waits:

select SID, state, event, p1, p2
from v$session
where username = 'ARUP';

SID  STATE     EVENT                   P1 P2
———— ———————   ——————————————————————— —— ————
2201 WAITING   db file sequential read  5 3011



The P1 column shows the file ID, and the P2 column shows the block ID. From that information in the above result, we can get the segment name from the extent information in DBA_EXTENTS, as shown below:

select owner, segment_name
from dba_extents
where file_id = 5
and 3011 between block_id
and block_id + blocks;

OWNER  SEGMENT_NAME
—————— —————————————
ARUP   T1


This shows that the T1 table, owned by ARUP, is being selected from by the disk in the session. We should direct our attention to this table for tuning. We can move the table to a high-speed disk for faster I/O, or, alternatively, We can focus on making I/O in this table faster by making changes that affect this table, such as creating new indexes, creating materialized views, or building a result cache.

These are the just few general guideline. We can enjoy it most when we really face this situation... :)

Suggestions are most welcome!!!


Credit- http://dbakeeda.blogspot.com/2016/04/how-to-troubleshoot-slow-running-query.html

Wednesday, April 22, 2020

EM agent start fails With 'java.lang.OutOfMemoryError'


I will show how to solve EM Agent failing to startup related to java memory problems.

Suddenly i found my agent is not starting with error Failed. So now its time to find issue and need to fix.

I have checked multiple logfiles but found this error in emagent.nohup, there was an error related to java memory:


It was an "Out of Memory Exception". To solve it, I had to increase the java heap space allocated to emagent.

(Reference Oracle Doc Id- 1399201.1)

Edit '$AGENT_BASE/agent_inst/sysman/config/emd.properties' and increase the memory allocated to 512M.

Before-

cat emd.properties | grep agentJavaDefines

agentJavaDefines=-Xmx128M -XX:MaxPermSize=96M

After-

cat emd.properties | grep agentJavaDefines
agentJavaDefines=-Xmx512M -XX:MaxPermSize=96M

Now Try to restart agent using "emctl start agent".

emctl start agent
Oracle Enterprise Manager Cloud Control 12c Release 5
Copyright (c) 1996, 2015 Oracle Corporation.  All rights reserved.
Starting agent ..................... started.

 if you still face any issues, you will need to clear the agent state and retry.
Do the following:
  1. Stop and kill any remaining process related to EM Agent that is still running (perl or java).
  2. Clean all files from '$AGENT_BASE/agent_inst/sysman/emd/state/*' folder (or move them to a temporary place).
  3. Clear agent state by running: emctl clearstate agent.
  4. Increase the memory allocated editing emd.properties, as showed before, if not already done.
  5. Try to start the agent again.










Monday, March 30, 2020

Redo and Undo Generation 


To find sessions generating lots of redo, you can use either of the following 
methods. Both methods examine the amount of undo generated. When a transaction 
generates undo, it will automatically generate redo as well.

The methods are:
1) Query V$SESS_IO. This view contains the column BLOCK_CHANGES which indicates
   how much blocks have been changed by the session. High values indicate a 
   session generating lots of redo.

   The query you can use is:

       SQL> SELECT s.sid, s.serial#, s.username, s.program,
         2  i.block_changes
         3  FROM v$session s, v$sess_io i
         4  WHERE s.sid = i.sid
         5  ORDER BY 5 desc, 1, 2, 3, 4;

Run the query multiple times and examine the delta between each occurrence
   of BLOCK_CHANGES. Large deltas indicate high redo generation by the session.

2) Query V$TRANSACTION. This view contains information about the amount of
   undo blocks and undo records accessed by the transaction (as found in the 
   USED_UBLK and USED_UREC columns).

  The query you can use is:

      SQL> SELECT s.sid, s.serial#, s.username, s.program, 
        2  t.used_ublk, t.used_urec
        3  FROM v$session s, v$transaction t
        4  WHERE s.taddr = t.addr
        5  ORDER BY 5 desc, 6 desc, 1, 2, 3, 4;

   Run the query multiple times and examine the delta between each occurrence
   of USED_UBLK and USED_UREC. Large deltas indicate high redo generation by 
   the session.

You use the first query when you need to check for programs generating lots of 
redo when these programs activate more than one transaction. The latter query 
can be used to find out which particular transactions are generating redo.


Friday, March 27, 2020

Unregistered Database From RMAN Catalog


If we need to unregister database from recovery catalog so we have two option-

1> Need to connect from target server and using RMAN easily we can unregister.

2> Suppose in a case if we dont have database(someone dropped) and we need to clear this from             rman catalog server then


Sol-

Connect to rman catalog server, then connect to rman user or whatever is catalog user we have then do needful as below.

SQL>  Conn rman/rman

       Below is the query by which we will get command which we need to execute, so we need to    pass DB_NAME in my case DB_NAME is TEST.

SQL> select 'EXECUTE dbms_rcvcat.unregisterdatabase('||db_key||','||dbid||');' FROM                           rc_database WHERE name in('TEST') ;


SQL> 'EXECUTEDBMS_RCVCAT.UNREGISTERDATABASE('||DB_KEY||','||DBID||');'
--------------------------------------------------------------------------------
EXECUTE dbms_rcvcat.unregisterdatabase(36631376,3102016920);

SQL> select db_key,DBID,NAME from rc_database where name='TEST';

    DB_KEY       DBID NAME
---------- ---------- --------
  36631376 3102016920 TEST

SQL>EXECUTE dbms_rcvcat.unregisterdatabase(36631376,3102016920);

PL/SQL procedure successfully completed.

Wednesday, July 17, 2019

How to understand AWR report in Oracle11g?


Let we discuss about How to understand AWR report in oracle11g?
* We already know the steps to generate AWR reports , but after you did this how can you read it .
To understand AWR report:
Step-1:
To check "DB Time"



Snap Id Snap Time Sessions Cursors/Session
Begin Snap: 1235 23 May 2017 10:30 191 6.7
End Snap: 1236 23 May 2017  11:31    173 7.4
Elapsed: 59.23 (mins)
DB Time: 710.73 (mins) 


In above scenario " DB time " metric is higher than elapsed time so it meaning session are waiting for something
Note:if the Dbtime is higher than elapsed time so the session must be waiting for something

STEP-2:
To View Instance Efficiency


 Instance Efficiency Percentages (Target 100%)
Buffer Nowait %: 100.00 Redo NoWait %: 100.00
Buffer Hit %: 98.67 In-memory Sort %: 100.00
Library Hit %: 98.60 Soft Parse %: 99.69
Execute to Parse %: 5.26 Latch Hit %: 99.31
Parse CPU to Parse Elapsd %: 12.78 %Non-Parse CPU: 99.10 
Note: As per the thumb rule, Instance Efficieny Percentages should be ideally above 90%.

STEP-3:
To Review Shared Pool Statistics



 Shared Pool Statistics
Begin End
Memory Usage %: 83.49 80.93
% SQL with executions>1: 42.46 82.96
% Memory for SQL w/exec>1: 47.77 81.03 
In above the memory Usage of shared pool statistics has been shown here now it seems 83 %
If suppose its higher than 90 % the conflict in the shared pool

STEP-4:
To View Top 5 Events


 Top 5 Timed Events
Event Waits Time(s) Avg Wait(ms) % Total Call Time Wait Class
db file sequential read 4,076,086 28,532 7 66.9 User I/O
CPU time 11,214 26.3
Backup: sbtbackup 4 4,398 1,099,452 10.3 Administrative
log file sync 37,365 2,421 65 5.7 Commit
log file parallel write 37,928 1,371 36 3.2 System I/O 
Here, the significant wait is the db file sequential read which contributes to 67% of DB Time.

STEP-5:
Then , SQL Statistics can be checked.

SQL Statistics
SQL ordered by Elapsed Time
SQL ordered by CPU Time
SQL ordered by Gets
SQL ordered by Reads 
SQL Statistics section would have commonly the above four sections.
Each section shows the list of SQLs based on the order of the respective metric.
For example, SQL ordered by Elapsed Time section shows the list of SQLs in the order of the Elapsed Time.
High resource consuming SQLs can be spotted out and meant for tuning.
Note: All the above four sections of SQL Statistics show the list of SQLs in descending order.
i.e, For ex: Highest elapsed time is shown as first.

STEP-6:
Then comes the IO Stats section.
This shows the IO Statistics for each tablespaces in the database.

Note:As the thumb rule, the Av Rd(ms) [Average Reads in milliseconds] should not cross beyond 30, add myself(not greater that 30) which is considered to be IO bottleneck.

Tablespace IO Stats
ordered by IOs (Reads + Writes) desc 

Tablespace Reads     Av Reads/s Av Rd(ms) Av Blks/Rd Writes Av Writes/s Buffer Waits Av Buf Wt(ms)
TEMP        3,316,082 933         4.91      1.00              28,840 8 0 0.00
DATA1      520,120     146 16.06 1.21 185,846 52 902 13.00
DATA3      93,411       26 42.82 2.98 13,442 4 16 23.13
DATA2      98,171       28 91.97 7.97 5,333 2 325 34.89 

In the above example, the Av Rd(ms) is high in all tablespaces indicating the IO contention.

STEP-7
To verfiy Advisory Statistics

This section shows the following:-

Buffer Pool Advisory
PGA Aggr Summary
PGA Aggr Target Stats
PGA Aggr Target Histogram
PGA Memory Advisory
Shared Pool Advisory
SGA Target Advisory
Streams Pool Advisory
Java Pool Advisory 
It is very commonly used to check the advisories for the most important SGA structures like shared pool, buffer cache etc and PGA.

STEP-8
Then finally, init.ora Parameters is shown which shows the list of parameters set at instance level.

init.ora Parameters
All the above said sections except the DB Time can be checked from Statspack report also.
The statspack snapshots are not generated automatically as in AWR.It has to be generated during the problem period as follows:-
Take 2 snapshots between 60 minutes interval during the problem and generate the statspack report

exec statspack.snap
wait for 60 minutes
exec statspack.snap

Please run $ORACLE_HOME/rdbms/admin/spreport.sql
and specify BEGIN and END ID's of the snapshots taken during the problem.

Tuesday, July 16, 2019

Performance Tuning In Oracle 11g - Part 1



 Performance Tuning is the improvement of system performance. The motivation for such activity is called a performance problem, which can be real or anticipated.
 - Most systems will respond to increased load with some degree of decreasing
Performance.
 - Oracle Performance method  is iterative  and DBA Core business is to improve performance
 - Performance tuning comes with  experience and resolving real-time bottleneck issues    
 I) Types of Performance Tuning:
 *Proactive  Tuning 
 - In design, development, testing stage -In production => ADDM(Automatic Database Diagnostic Monitor) -In this proactive, we have to check the database design, product development and test that.
 - After the  product  launch if we have any issues in building level run the ADDM adviser it gives appropriate built-in issue and recommendations to  DBA what is going on database background  
 *Reactive Tuning
 - In production, the problem has occurred
II) Resolving Performance issues:
 - If any performance issue occurred it can be resolved  by below
resolvePFT
1)Tuning outside Database (DBOUTSIDE)
 - if any issues happened in performance level first  we need to  identify    the os level, network, storage  levels everything is going  good or not
- Once  you  confirmed there are no issues on outside the DB, then go  to inside the database level 2
2)Database tuning (DBINSIDE)
*Again we adopt the top-down approach
   - Tune the design
   - Tune the SQL queries
   - Tune the various memory structure of instance level
III) Methodology
  - Tuning Methodology to identify  the performance (problem ) issue where it happened and resolve using the below methodology
    *Monitor   - To monitor the issue where the problem has occurred
    *Diagnose - To identify the root cause
    *Tune - To resolve the issue
1)Monitoring Tools
Montior tools  
     *user Feedbacks
       - To get a query about the user  performance issue
      - If user  raise the complaints that time only we know the issue
     *Dynamic Performance View
      - These views owned by SYS users
      - Reside in-memory  values
      - All reads on these views are current reads
      - These cumulative values since  instance startup
      - We can refer to these views "V$dollar view names"
     - By using this view we can collect  statistics  collect tune investigation
  1)Instance Activity
  The statistics which collect information about the instance.
  - Overall statistics are listed in V$STATNAME
      Eg:
    *Parse time CPU
    *Physical reads
    *User commits
  - Cumulative Instance activity
    *Session level
  - V$SESSTAT
    *System level
  - V$SYSSTAT  
2)Wait Events
  The event  for which process is waiting  to be over  before it processed  
  - Provides information about sessions that  had to wait or must wait for different reasons
  * Overall wait events
- V$EVENT_NAME
  * Instance Level wait event in system level
- V$SYSTEM_EVENT
  * Session Level wait events waited in past
- V$session_event currently waiting
- V$session
3)Metrics
 - Rate of changes in cumulative statistics
 - Computed real-time  in MMON
  *Alert Log
 - Time to perform archiving
 - Instance recovery start and complete time
 - Incomplete checkpoints -Checkpoints start and end time
  *Enterprise Manager
 - We can access the database through the browser
 - Start and stop the database  
  Let us see one example of performance tunning   logged on sys user and check the user, account status from dba_users tables
   SQL>select username ,account_status from dba_users;
here we can choose Scott and hr  users and then we can give the permission emp table of Scott into hr
   SQL> Grant select ,update on scott.emp to hr;
here we logged into Scott user and tried to update the sal column of EMP
  SQL>update emp set sal=sal+5 where empno=7900;
     1 row updated
after this update we won't give commit or rollback next we go to other sessions in that name of HR login as the same thing we do
  SQL>update emp set sal=sal+5 where empno=7900;
now HR is waiting for Scott once we get  problem issue from development side first we ensure who are all in on-line
    SQL> select sid,serial#,username from V$session;

       SID    SERIAL# USERNAME
   ---------- ---------- ------------------------------
         1          5 SYS
         2          1
         3          1
         4          1
         5          1
         6          1
         7          1
         8          1
         9          1
        10          1
        11          1
        12          1
        13          1
        14          1
        15          1
        16          1
        20          2
        22          2
        24          3
        25         99
        29          3
        30         12
        31         16
        32         50
        33          3 HR
        34         15 SCOTT
  S-2: to wait out both user what is the status  
  SQL> select sid,event,seconds_in_wait,wait_time,state from V$session where sid in('33','34');

       SID EVENT                                                            SECONDS_IN_WAIT  WAIT_TIME STATE
       ---------- ---------------------------------------------------------------- --------------- ---------- -------------------
        33 enq: TX - row lock contention                                                829       0 WAITING
        34 SQL*Net message from client                                                  914       0 WAITING

  here the problem is "ENQ: TX- row lock contention" means that sid is waiting for someone
 S-3: let us find  CPU usage in system level  
    SQL> select  event,time_waited from V$system_event where event='enq: TX - row lock contention';

    EVENT                                                            TIME_WAITED
    ---------------------------------------------------------------- -----------
    enq: TX - row lock contention                                         154390

     SQL> /

     EVENT                                                            TIME_WAITED
    ---------------------------------------------------------------- -----------
    enq: TX - row lock contention                                         158326

  S-4: find which session is waiting for session-level
   SQL> select sid,event,time_waited from V$session_event where event='enq: TX - row lock contention' and sid in ('33','34');

       SID EVENT                                                            TIME_WAITED
      ---------- ---------------------------------------------------------------- -----------
        33 enq: TX - row lock contention                                         175386
  S-5: find out how the user has been logged
     SQL> select event,service_name,total_waits,time_waited,average_wait,max_wait from V$service_event where event='enq: TX - row lock contention';
  
         EVENT                                                            SERVICE_NAME                  TOTAL_WAITS TIME_WAITED AVERAGE_WAIT    MAX_WAIT
    --------------------------------------------------------------- ---------------------------------------------------------------- ----------- ----------- ------------ ----------
           enq: TX - row lock contention                                    SYS$USERS                       1       190688       190688          0
S-6: to find the blocked  session user
        SQL> select  BLOCKING_SESSION_STATUS, BLOCKING_INSTANCE, BLOCKING_SESSION ,username from V$session where sid in('33','34');

          BLOCKING_SE BLOCKING_INSTANCE BLOCKING_SESSION USERNAME
          ----------- ----------------- ---------------- ------------------------------
           VALID                       1               34 HR
          NO HOLDER                                      SCOTT
S-7: to find the object _id because using this id we can find which  has been trouble
       SQL> select ROW_WAIT_OBJ#   "Object_id" ,ROW_WAIT_FILE# "realtive fileno", ROW_WAIT_BLOCK#   "Block Number" from V$session where sid in('33');

                   Object_id realtive fileno Block Number
                  ---------- --------------- ------------
                    73181               4          151
S-8: to find the table problem occur table and owner
      SQL> select owner,object_type,object_name,data_object_id from dba_objects where object_id='73181';

      OWNER                          OBJECT_TYPE         OBJECT_NAME                                                DATA_OBJECT_ID
     ------------------------------ ------------------- ---------------------------------------------------------------------------------------------------------------------------        ----- --------------
          SCOTT                          TABLE               EMP                                                         73181
S-9:   to find out user details
 


       SQL> select machine,osuser,username ,sid,service_name,logon_time from V$session where sid in ('33','34');

          MACHINE                                                          OSUSER                         USERNAME        SID SERVICE_NAME                                                                  LOGON_TIM
---------------------------------------------------------------- ------------------------------ ------------------------------ ---------- ---------------------------------------------------------------- ---------
         goldengatesource                                                 oracle                         HR               33 SYS$USERS                                                                  12-MAR-16
        goldengatesource                                                 oracle                         SCOTT            34 SYS$USERS 

S-10: to sql_id for SQL query which has been issued
     SQL> select sql_id from V$session where sid in ('33','34');

         SQL_ID
       -------------
        1dc2pgg0uh57f
S-11:   finally we found the issue query which has been given hr user now we ensure whether user Scott is going to commit or kill that session get the conformation application team.
     SQL> select sql_fulltext from  V$sql where sql_id='1dc2pgg0uh57f';

      SQL_FULLTEXT
     -------------------------------------------------------------------------------- 
      update scott.emp set sal=sal-3 where empno=7900 


Credit-https://ampersandacademy.com