Oracle大并发的OLTP系统优化的几点建议

       Oracle数据库对高并发有着非常好的支持。高并发的系统必然产生大量读写操作(DML),进而产生大量事务,也就会消耗大量的锁资源,特别是行锁。Oracle行锁物理上是在数据块上面实现的,因此ORACLE锁资源几乎是无限的,而其他数据库是通过内存实现的锁机制(比如db2),如果内存不足行锁就会升级为表锁,造成锁升级。而且,oracle的读写操作不互相阻塞,对高并发操作也有很大好处。

        Oracle数据库在高并发环境下还是要注意以下问题,以提高系统性能,防止造成性能瓶颈:

        一、OLTP数据表(不同于OLAP数据表)一般都要有主键,对于大并发系统,不要用sequence作为主键。这是因为,索引是有序存储的,默认是按升序存储。在大并发情况下,很多进程进行insert操作,索引要进行更新,如果用sequence作为主键,索引更新就会集中在最大的那个索引块。索引块更新是排它的而不是共享的,很多进程同时更新,同一时间只能有一个进程执行更新,这就造成了排队,从而性能下降。解决方法可以使用uuid等方式,只要不是递增的就行,使更新分散在多索引块上。


        二、经常有这样的场景,一条sql查询语句在系统比较空闲时,反应很快,但在业务繁忙被很多个进程同时更新时,反应速度急剧下降,查看执行计划会发现逻辑读大幅上升,逻辑读增加会消耗大量资源,特别是CPU。造成这种现象是因为Oracle为了维护数据的一致性,当查询某些数据的时候,发现数据块的版本比我们要查询的新,例如session1执行了dml操作并没有提交,session2此时查找跟session1相关的dml操作的数据信息,此时查询的数据却是原来的数据信息。查询的过程会在undo段中查找该数据块的前映像后,然后把前映像和current块合并形成了一个CR block,通过查询cr block就可以满足数据的一致性了。当系统繁忙时,可能有大量未提交事物,也就造成逻辑读增加,也就是要解析的块增加,CPU就吃不消了。

         解决方法是:

         1.优化查询sql,使它的查询速度尽可能达到可接受程度;

         2.优化DML SQL(或者业务流程),使它尽快的提交,释放掉UNDO段中的数据。

         3.如果优化达不到目的,可以从系统设计上解决,分库,分表,分业务,数据切割,内存数据库,缓存经常执行的SQL等等,但是成本太高了。


        三、一个高并发系统,要保证sql执行计划稳定,也就需要统计信息准确,可以选择每天晚上在数据库不繁忙的时候运行脚本,收集统计信息。但是高并发系统不能随便进行动态采样。动态采样会根据采样级别扫描数据块,并且还会隐式的执行SQL(一个sql会隐含出发多个sql),进行统计信息收集,特别是如果搞个全库动态采样( alter system set optimizer_dynamic_sampling=6;)。这样系统会造成性能急剧下降,造成宕机。


你可能感兴趣的:(Oracle大并发的OLTP系统优化的几点建议)