最近公司项目二期开始了,甲方一直反应的数据库运行缓慢的问题,再也绕不过去了。这个项目我刚接手,对于这样的项目,通常也就是这几部。
1.通过PLSQL Developer,TOAD 等CASE工具得到系统的PDM或CDM来,特别关注几个大的驱动表。
在这个项目中我们有三个大的表,一个是底层数据采集的TABLE_SDATA,还有一个是同上层交互数据存储表TABLE_UPLOAD,还有一个是记录用户操作的TABLE_STATUS表,在没有脏数据的情况下,这三个表基本上是10:8:8 ,总体数据有上亿条数据。
俗话说的好,好钢用在刀刃上,充分分析这几张表后,心里有些底。TABLE_DATA经常一起连同4-5数据字典表做JOIN 查询。很多查询同时需要TABLE_UPLOAD和TABLE_DATA这两张表连接,这是一个问题。 TABLE_STATUS会同一些组织结构,用户自管理的表JOIN 问题也不会很大。
于是基本上先盯住TABLE_DATA和TABLE_UPLOAD 这两个用电大户。
2.再通过项目经理了解甲方生产环节的存储规划,表空间规划,内存规划等情况。因为这一块是外包给咨询公司的,心里确实也不放心。要知道现在一个
会一点Linux的,可以装装ORACLE10G 的毕业生,也能把用户忽悠的团团转。
得到相关信息后证明了我的担忧。
主要问题有:
系统中对大表使用大量的索引,这些索引和其他数据都放在一个持久化表空间中,这样索引会同数据查询产生IO竞争。
系统中存有BLOB大数据,这些大数据没有进行优化,虽然使用了Raid 1+0 可以平衡IO 但是在查询的时候没有分区,会影响访问的速度。
系统中驱动表 对数据没有做分区。基本查过2G经常查询的数据,ORACLE的建议 都需要做分区的。
系统管理员 不清楚是否使用了CBO 优化。
3.对系统有了了解后,联系好了对方系统管理员,需要他可以把AWR报告发给我一份 。
收到了AWR报告后,一看Top5 waitevent 把我吓的一跳
EVENT WAITS TIME(S) AvgWait %TotalCallTime WaitClass
CPU time 3032 40.2
db file scattered read 3,724,033 1.508 0 20.9 user i/o
read by other session 203.470 824 4 10.9 user i/o
latch:catche buffers chains 31.580 487 15 6.5 concurrency
db file sequential read 243.794 291 1 3.9 user i/0
db file scattered read 排第1,全表扫描,这肯定是我们的程序设计中SQL的问题,这个没有办法耍赖的!
read by other session 全表扫描多了,这个事件肯定也会多的,还有上面我提到的i/o 竞争的问题。
latch:catche buffers chains 当一个会话需要去访问一个内存块时,首先需要去访问一个链表类似的结构是否存在内存中,当其他会话访问时,需要一个latch,如果latch获取失败则肯定会有这个事件。
导致的原因是系统有热块,这个需要进一步分析。
对其中的CPU 做了分析,8颗CPU,CPU在每秒中消耗的单位为 140个,实际对应的时间为1.40s,
然后1.40/8=0.17 s 说明数据库CPU的资源是丰富的,远没有瓶颈。
基本上吧优化重点 对准我们系统性能差的SQL
4.上层的应用系统比较乱,Hibernate 和 IBatis 的ORM框架都有。
首先找到了 几个驱动表的SQL查询,发现分页时,谓词使用了like,在过滤时也使用了大量的or关键词,这些性能比较差,更改后性能没有很大提高。
其次,忘了确认索引,查看索引后 发现在一个驱动表中,对时间,和value竟然使用的是bitmap 索引,吓的我一生冷汗,该驱动表是一个数据采集表和
数据查询表 有大量的DML 和DQL 使用bitmap会引起会话挂起. 然后经常查询的地点没有加入索引。
更改后 查询性能提高60%。
表操作的速度还是比较慢。开始在表结构上下工夫。
5.对几个大的驱动表做在线的表分区。