设为首页 收藏本站
查看: 655|回复: 0

[经验分享] Discovering Bad SQL

[复制链接]

尚未签到

发表于 2016-11-9 06:49:03 | 显示全部楼层 |阅读模式
  

--it comes from TOAD WORLD (http://www.toadworld.com/KNOWLEDGE/KnowledgeXpertforOracle/tabid/648/TopicID/BDSQL/Default.aspx)
There are basically three scenarios that you will encounter:



  • You will need to discover what caused a performance problem that occurred at some time in the immediate past

  • You need to find out why the overall system is performing poorly at this time

  • You need to find out why a particular process is performing poorly at this time.

Successful discovery of the first problem is usually dependent on whether or not you had your Statspack, Oracle 10g's Automated Workload Repository (AWR) data captures or, or third-party data collection running, although the dynamic performance views might be helpful as well. Successful resolution of the second and third scenarios will require a process or methodology that uses the V$ dynamic performance views to discover bad SQL, and then to explain why the SQL performs poorly. So, let's look at usingat using the V$ views to discover current bad SQL.
Discovering the Cause of Poor Performance


Ok, so your database is performing poorly all of a sudden, and no one knows any particular reason why. We can call this scenario troubleshooting with no information. These types of problems can easily be due to one or more rouge SQL or processes. Regardless, the DBA is usually tasked with discovering the offensive processes and bad SQL, given only the database name and no further information.

The V$ Views and Queries


Since you don’t already know which process or processes are consuming system resources, you need to discover this information quickly. Here are some basic things to look for:




  • locking/blocking/waiting

  • high CPU utilization

  • undo or rollback issues

  • wait issues

  • IO issues

  • Top-n SQL

Locking Issues


Before determining if you have poorly tuned SQL, you need to determine if instead you have a locking issue. Run catblock.sql immediately after the database has been built and the basic packages installed, then query DBA_BLOCKERS and DBA_WAITERS to discover sessions that are blocking other sessions:


SQL> select * from dba_blockers;
HOLDING_SESSION
---------------
12
If no rows are returned, we eliminate locking as a performance problem, and start to investigate SQL. If there is blocking, then you need to determine what is causing it and deal with the issue. Blocking can be a troublesome problem in it's own right. Querying DBA_BLOCKERS can take a long time to return rows of data. Many DBA's prefer to query V$LOCK instead. The downside to the V$LOCK view is that it is much harder to read and interpret the data. The following query can be used against V$LOCK.

SELECT sid,type,id1,id2,lmode,request
FROM v$lock;
A session will be waiting on a lock to be released if the REQUEST column is non-zero. That session is waiting for a certain type of lock. To find the session that is holding that lock, look for the same ID1 and ID2 values for the same TYPE in another session.
In addition to the database views, Oracle's Enterprise Manager can be used to detect blocking. The following screenshot shows on user blocking another:

http://kevin010.iyunv.com/Portals/0/Kx/Img/BDSQL_224.gifIn this case, SCOTT is blocked by SYSTEM. Selecting one of the radio buttons and pressing the Kill Session button will terminate one of these sessions. There are many links to be able to drill down for further information.
CPU Issues


As the DBA, you should have access to the database server, and OS commands that you can use to discover the process id (PID) of the top CPU consumers:




  • Unix: top, topas, ps – ef | grep ora

  • Windows: NT Task Manager

You can relate the system processes to the database sessions in the v$process table. For Unix, the PID is the same as the SPID column in v$process. For Windows, the PID is the same as the first part of the PROCESS column in v$session. Here is an example of finding the sid and it’s associated process on an Oracle NT Database.


-- Run on NT
Select sid, serial#, process
from v$session
where username is not NULL;
SID           SERIAL# PROCESS
---------- ---------- -------
9         33 315:338
10        258 346:345
12          7 352:351
On Oracle for UNIX the query would look like this:

Select a.sid, a.serial#, b.spid
from v$session a, v$process b
where username is not NULL
and a.paddr=b.paddr;
SID           SERIAL# PROCESS
---------- ---------- -------
9         33 11332
10        258 11322
12          7 12211
Select a.sid, a.serial#, b.spid

from v$session a, v$process b

where username is not NULL

and a.paddr=b.paddr;

SID           SERIAL# PROCESS

---------- ---------- -------

         9         33 11332

        10        258 11322

        12          7 12211
Also, the CPU_TIME column of the V$SQLAREA view indicates how much CPU time has been used by the query. One thing to keep in mind is that CPU time is cumulative for all executions of this particular SQL. The following query looks at the SQL statement that has consumed the most CPU time, providing us with a tuning candidate:



select fetches, executions, a.parsing_user_id, a.cpu_time, a.sql_text

from v$sqlarea a, dba_users b

where cpu_time = (select max(cpu_time) from v$sql)

and a.parsing_user_id=b.user_id

and b.username not in ('SYS','SYSTEM')

/


FETCHES    EXECUTIONS CPU_TIME

---------- ---------- --------

SQL_TEXT

----------------------------------------------------------------

      2296       1232    11134

select * from emp where empno not in (select empno from bad_emp);




Here we see that a SQL statement has 2296 fetches for 1232 executions and a large amount of CPU time. We would probably want to investigate this situation further and determine if there is some tuning that can be done for this statement.

Undo or Rollback Issues


If a transaction is consuming large amounts of rollback, you’ll be able to identify it with this query:



select a.sid, a.serial#,

       substr(b.owner,1,8) "schema",

       substr(b.object_name,1,20) "object Name ",

       substr(b.object_type,1,10) "type ",

       substr(c.segment_name,1,8) "rbs ",

       substr(d.used_urec,1,12) "# of records "

from   v$locked_object l,

       dba_objects b,

       dba_rollback_segs c,

       v$transaction d,

       v$session a

where  l.object_id = b.object_id and

       l.xidusn = c.segment_id and

       l.xidusn = d.xidusn and

       l.xidslot = d.xidslot and

       d.addr = a.taddr

/

SID      SERIAL# schema   object Name        type       rbs      # of records

----- ---------- -------- ------------------ ---------- -------- ------------

   10        258 HR       EMPLOYEES          TABLE      _SYSSMU2 12




In this case SID 10 is accessing the HR.EMPLOYEES table. Only 12 records are being accessed, not a large amount at all, so we probably wouldn’t worry about this session.

Session Wait Issues


You can also determine what sessions are in a particular wait event, and for how long.



select sid, event, seconds_in_wait

from v$session_wait

where sid in (select sid from v$session where username is not NULL)

/

SID   EVENT                                    SECONDS_IN_WAIT

----- ---------------------------------------- ---------------

    9 null event                                             0

   10 SQL*Net message from client                          778

   12 SQL*Net message from client                         3119

   22 Buffer Busy Wait                                     222




In this case, session 22 is experiencing buffer busy waits, and has experienced 222 seconds of them. This would certainly be something we would want to investigate quickly.

I/O Issues


The easiest way to find potential IO issues is to query the V$SESSIO view, sorted by the PHYSICAL_READS column:



select * from v$sess_io

where sid in (select sid from v$session where username is not NULL)

order by physical_reads

/

SID   BLOCK_GETS CONSISTENT_GETS PHYSICAL_READS BLOCK_CHANGES CONSISTENT_CHANGES

----- ---------- --------------- -------------- ------------- ------------------

   10         21              65              1            35                  0

   12          3              64              2             4                  0

    9        121          212893           2399             8                  0




In this listing, we see that session SID 9 has a large number of consistent gets. You would want to determine just what this session is up to, and try to tune the SQL appropriately.

Top-N SQL


Query the V$SQL view to determine the top-N queries by resource utilization. In the following query, we sort by CPU utilization:



SELECT * FROM

(SELECT cpu_time, elapsed_time, disk_reads, buffer_gets, rows_processed, executions,

sql_text from v$sql order by cpu_time desc)

WHERE ROWNUM < 6

/

CPU_TIME   ELAPSED_TIME DISK_READS BUFFER_GETS ROWS_PROCESSED EXECUTIONS

---------- ------------ ---------- ----------- -------------- ----------

SQL_TEXT

----------------------------------------------------------------

  52843750     64212467        150      228183          11858        539

select t.schema, t.name, t.flags, q.name from system.aq$_queue_tables t, sys.aq$_queue_table_affinities aft, system.aq$_queues q where aft.table_objno = t.objno and aft.owner_instance = :1 and q.table_objno = t.objno and q.usage = 0 and bitand(t.flags, 4+16+32+64+128+256) = 0 for update of t.name, aft.table_objno skip locked


  15265625     17625255          1       83258          11858      11858

select t.name, (select owner_instance from sys.aq$_queue_table_affinities where table_objno = t.objno) from system.aq$_queue_tables t where t.name = :1 and t.schema = :2 for update skip locked

......




This type of query is extremely useful at determining the actual SQL that contributes to poor performance. In the case of this output, there would not be a great deal we could do as this all appears to be recursive SQL associated with advanced queuing. However, it might be that if we are not using advanced queuing we might disable the feature and eliminate this SQL from executing.



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-297656-1-1.html 上篇帖子: sql备份数据库 下篇帖子: IBatis SQL 映射
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表