使用AWR报告诊断oracle性能案例

一 问题描述

同事反馈某台oracle数据库压力比较大,服务器cpu使用率达到了70%多,想让看看怎样优化。

二 问题排查思路

2.1 生成AWR性能诊断报告

#登录数据库

su - oracle

sqlplus / as sysdba

#生成awr报告:

@?/rdbms/admin/awrrpt.sql

示例:

这里想分析11月24日9点至22点的oracle性能状况,因此需要指定该时间对应的snap Id:

 文件默认放在/home/oracle下。

将该文件下载到本地,用浏览器打开即可。

2.2 分析AWR报告

2.2.1 查看数据库整体性能

可以看到数据库比较繁忙(DB Time接近或者大于 Elapsed * CPUs,说明数据库繁忙)。

2.2.2 查看等待事件

可以看到top 1等待事件是DB CPU。

2.2.3 查看消耗资源的sql

点击‘SQL Statistics’:

 可以看到有两个sql比较消耗DB Time。

点击SQL id,可以查看详细的sql语句。

2.2.3.1 Top1 sql

select COUNT(*) from EDU_COURSE_CLASS_STUINFO where CLASS_ID=:1

可以看出每秒执行12次这个sql,平均每次执行需要1秒钟。

我自己手动执行了下,这个sql很快就执行完了(0.几秒),数据库层面几乎没有优化的空间了,奈何这个sql执行频率太高,同事计划通过缓存来解决。

2.2.3.2 Top2 sql

select * from SYNDATA where synflag=:1 order by createtime

这个sql在synflag=不同值条件下,查询时间不一样。

这个表有三百多万条数据,在=1的情况下,执行需要16秒,在=2的情况下=1秒。

由于synflag重复值比较高(唯一值只有三个值),不适合建索引。因此这个sql走的是全表扫描。

执行计划:

 在createtime建了索引后,发现也并没有变快。

跟开发同事沟通了下,这个sql的业务是去同步所有synflag=某个值的数据。

这个sql只有synflag=:1这一个条件,频繁地(平均每秒查询3此)扫描一个大表,比较消耗性能。

感觉没有必要去这么频繁地查一个表的这么多数据。在不影响业务的前提下可稍微改下业务逻辑,只根据createtime来同步今天的数据,可大大提升性能(前提是在createtime上建个索引),每天晚上再去除时间的限制去自动同步一次全量数据即可。

改后的sql:

select * from SYNDATA where synflag=:1 and to_char(sysdate, 'yyyymmdd')<=createtime order by createtime

同事按建议优化后,查询效率得到很大提升:

平均执行时间由原来的1秒降到了0.1秒,也不再消耗DB Time了:

猜你喜欢

转载自blog.csdn.net/yabignshi/article/details/121544370