Oracle有很多值得学习的地方,这里我们主要介绍Oracle数据库对象,包括介绍Oracle实例等方面。每一个Oracle实例都是由一组Oracle后台进程和SGA的一个内存区组成的。这组后台进程会自动的读写数据库的数据文件,数据库性能可以被这些因素所影响:
◆SGA各部分的分配是否合理,使用效率是否正常;
◆I/O和锁竞争是否较多。
1.SGA的分配及使用效率
分配给每个实例的内存,即SGA的使用效率如何,会大大影响数据库系统的性能。SGA由下列部分组成:共享池、数据块缓冲区、重做日志缓冲区、大池组成。
共享池存放库缓存(存储共享SQL和PL/SQL区)和数据字典缓存(Oracle数据库对象信息)以及会话期间信息(对于MTS)。由于这些信息是应用程序需要经常访问的,因此这些信息需要保持高的命中率。可以通过以下语句来确认共享池数据的命中率:
◆库缓存:
- select gethitratio from v$librarycache 应大于90%
- select sum(reloads)/sum(pins) from v$librarycache 应小于1%
◆数据字典缓存:
- select sum(getmisses)/sum(gets) from v$rowcache 应小于15%
由于程序设计人员的水平参差不齐,可能存在大的匿名块,这会导致SQL不能重用,因此需要找出大的匿名块以转换为存储过程达到重用:
- select * from v$sqlarea where command_type=47 and length(sql_text)>500
而对于一些应用系统非常频繁使用的SQL对象如存储过程、函数、包等,可以通过钉在内存中的方式来防止由于共享池太小被移出:
- exec dbms_shared_pool.keep
◆数据块缓冲区(Db block buffer):
数据块缓冲区存放用户所经常访问的数据文件的数据块内容以及用户修改的数据内容。数据库把数据文件里的内容读到内存中,下次需要时直接从内存中读取,从而减少了磁盘的I/O和响应时间。当然,一般只在比较小的数据表(如常用代码表)才缓存到内存中。
由于数据快缓冲区中不可能存放所有的数据,因此可使用LRU算法来确定移出哪些数据块,但又尽量保证有较高的数据命中率。
查看数据块命中率的SQL语句为:
- select 1-(phy.value/(cur.value+con.value))
from v$sysstat cur,v$sysstat con,v$sysstat phy- where cur.name='db block gets' and con.name='consistent gets'
- and phy.name='physical gets'
如果这个命中率小于0.85,就要考虑为数据块缓冲区分配更多的内存了。
◆重做日志缓冲区(Log buffer):
重做日志缓冲区存放从用户内存区复制来的每个DML或DDL语句的重做条目。如果这个缓冲区分配太小会导致没有足够的空间来放重做条目而等待。
2.I/O和资源竞争
由于有众多的进程要写数据文件,因此需要通过I/O调整来解决I/O瓶颈问题。如果在设计阶段有效地考虑了表空间的合理分配,就能有效地在一定程度上减少I/O竞争。在数据库运行时,由于数据的动态增长,原来分配给表或索引的空间已经用完,Oracle会自动分配空间给这些Oracle数据库对象。而这个动态分配会对系统性能有所影响,所以要求:
避免动态空间管理
表空间的本地化管理,以减少与数据字典表空间的磁盘竞争。
在系统设计和试运行阶段数据量相对较小,效率低下的SQL可能并不会影响系统响应时间,但当系统数据量增长到一定程度时,需要在系统运行时监控并找出是哪些SQL不能有效使用索引或缺少索引,并进行相应调整:建立索引;修改SQL写法。
另外,在Oracle中,需要采用一些机制来保证Oracle数据库对象在使用期间的稳定性和数据的一致性,如使用锁存器(latch)、锁(lock)等。因此争用和这些机制相关的资源会影响数据库的性能。为了减少这种资源竞争,可以通过调整数据库的相关初始化参数(如db_block_lru_latches、 dml_locks)来减少资源的争用,优化数据库性能。
【编辑推荐】