监测oracle sql执行,TOP SQL监控之oracle篇

本文介绍了在Oracle数据库中监测和优化SQL的方法,包括根据进程PID查找SQL、查看当前执行中的SQL、检查最近执行的SQL、分析过去七天的SQL以及利用AWR报告。这些技巧有助于快速定位和解决性能问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库SQL的监控和优化的核心,其实主要在于“行读”!

监控找出行读高的SQL,而优化的最直接手段就是降低行读数。

oracle的监控方法和监控工具可能有千百种,这里介绍我常用的几种简单而直接的方式:

注意:以下监控SQL需要用户有oracle的管理视图查询权限。

1、根据pid查SQL

2ca979bdbbc71fc236a6cf6cb3bdc6db.png

假如你的oracle此时响应速度较慢,从服务器的TOP可以看到oracle进程占用了较多CPU,或者有较多的iowait,那么可以直接用下面的SQL语句来查询正在执行的较耗资源的SQL。

SELECT A.,B.SQLTEXT FROM

(SELECT z.SPID AS 操作系统PID

,x.SID

, x.SERIAL#

, x.USERNAME

, x.SQLID

FROM v$session x

, v$process z

WHERE x.PADDR = z.ADDR

AND Z.SPID = '10341')A

LEFT JOIN v$sql B ON A.SQLID = B.SQLID;

恭喜你,你可能已经直接找到有问题的SQL了。

608a8bac8ed116e32978c2a53d915834.png

2、正在执行中的SQL

如果不知道pid,那稍微改动下上面的SQL,可以直接查当前oracle库正在执行的所有SQL,按照时间倒序排序,一样能抓到最可疑的SQL。

SELECT z.SPID AS 操作系统PID

,x.SID

, x.SERIAL#

, x.USERNAME

, x.LOCKWAIT

, x.STATUS

, x.SCHEMANAME

, x.OSUSER

, x.PROCESS

, x.MACHINE

, x.PORT

, x.PROGRAM

, x.SQL_ID

, x.SQL_CHILD_NUMBER

, x.SQL_EXEC_START

, x.PREV_SQL_ID

, CASE x.ROW_WAIT_OBJ# WHEN - 1 THEN NULL ELSE (dbms_rowid.rowid_create (1, ROW_WAIT_OBJ#, ROW_WAIT_FILE#, ROW_WAIT_BLOCK#, ROW_WAIT_ROW#)) END AS rowinfo

, x.LAST_CALL_ET

, x.BLOCKING_SESSION_STATUS

, x.BLOCKING_SESSION

, x.FINAL_BLOCKING_SESSION_STATUS

, x.FINAL_BLOCKING_SESSION

, x.EVENT

, x.WAIT_CLASS

, x.STATE

, x.WAIT_TIME_MICRO

, y.SQL_TEXT

, y.EXECUTIONS

, CASE EXECUTIONS WHEN 0 THEN y.BUFFER_GETS ELSE y.BUFFER_GETS / EXECUTIONS END AS AVG_BUFFER_GETS

, CASE EXECUTIONS WHEN 0 THEN y.DISK_READS ELSE y.DISK_READS / EXECUTIONS END AS AVG_DISK_READS

, y.ELAPSED_TIME / 1000000 AS AVG_ELAPSED_TIME

, y.CPU_TIME / 1000000 AS AVG_CPU_TIME

FROM v$session x

, v$process z

, v$sql y

WHERE x.PADDR = z.ADDR AND x.SQL_ID = y.SQL_ID

--AND Z.SPID = 'XXXX'

--AND x.USERNAME='DEV'

AND x.STATUS = 'ACTIVE'

ORDER BY x.WAIT_TIME_MICRO desc;

3、刚刚执行过的SQL

如果是要查刚刚(由v$sqlarea存活时间而定)执行过的SQL中,哪些是比较耗资源的,可以试试下面这个:

SELECT *

FROM (SELECT EXECUTIONS

, BUFFER_GETS / EXECUTIONS AS AVG_BUFFER_GETS

, DISK_READS / EXECUTIONS AS AVG_DISK_READS

, ELAPSED_TIME / (EXECUTIONS*1000000) AS AVG_ELAPSED_TIME

, CPU_TIME / (EXECUTIONS*1000000) AS AVG_CPU_TIME

, SQL_TEXT

, SQL_ID

, SORTS / EXECUTIONS AS AVG_SORTS

, SHARABLE_MEM

, APPLICATION_WAIT_TIME / EXECUTIONS AS AVG_APPLICATION_WAIT_TIME

, CONCURRENCY_WAIT_TIME / EXECUTIONS AS AVG_CONCURRENCY_WAIT_TIME

, USER_IO_WAIT_TIME / EXECUTIONS AS AVG_USER_IO_WAIT_TIME

, ROWS_PROCESSED

FROM v$sqlarea

WHERE EXECUTIONS > 0 AND PARSING_SCHEMA_NAME<>'SYS'

AND LAST_ACTIVE_TIME BETWEEN to_date('2016-04-25 08:00:00','yyyy-mm-dd hh24:mi:ss') AND to_date('2017-07-25 12:00:00','yyyy-mm-dd hh24:mi:ss')

ORDER BY AVG_ELAPSED_TIME DESC) x

WHERE ROWNUM < 100;

修改ORDER BY AVG_ELAPSED_TIME DESC 为其他字段,比如 AVG_BUFFER_GETS就能查出哪些SQL的缓冲池读比较高。

注意:v$sqlarea是在内存中的,此SQL的查询时间范围没法太久远。

4、过去七天内执行过的SQL

如果是要查最近7天内执行过的SQL中,哪些是比较耗资源的,那我们可以改用dba_hist_sqlstat进行查询,它默认是存储7/8天的。不过需要预先知道dbid、instance_number、snap_id这几个数据,熟悉oracle的朋友应该清楚,awr报告的数据正是来源于此。

SELECT y.*,round(y.elap/y.exec,2) AS AVG_ELAP,z.SQL_TEXT FROM

(SELECT x.sql_id

, max (module) module

, sum (elapsed_time_delta)/ 1000000 elap

, sum (cpu_time_delta) cput

, sum (executions_delta) exec

FROM dba_hist_sqlstat x

WHERE x.dbid = 901548675 AND x.instance_number = 1 AND 5604 < x.snap_id AND x.snap_id <= 5612

AND x.MODULE = 'JDBC Thin Client'

GROUP BY x.sql_id)y

LEFT JOIN dba_hist_sqltext z ON y.sql_id = z.sql_id

WHERE y.exec >0

ORDER BY y.elap/y.exec DESC

5、AWR报告

如果以上4种方式还不足以解君之忧的话,那么还是来份AWR报告吧。

当然AWR报告也不是万能的,比如报告中TOP SQL的排序是按照总资源消耗倒序排序的,假设某些SQL执行次数很少但是单次消耗资源很多的,那可能会被掩盖掉而没有在报告中展示出来。

至于AWR报告如何生成如何解读,本篇不再赘述。

6、总结

以上介绍了几种非专业DBA快速定位oracle TOP SQL的方式,希望于君有益。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值