Oracle数据库高性能秘密之数据高速缓存

时间:2021-11-28 21:39:40

原文:http://www.php100.com/html/webkaifa/database/oracle/2009/0418/1348.html

使用过Oracle数据库的人都知道,Oracle数据库的运行速度与效率,在同类数据库中是名列前茅的,特别是对大量数据进行访问时,更加有出色的表现。那么,Oracle数据库是靠什么实现的呢?笔者下面将通过一系列的文章,向大家展示Oracle数据库提供高性能运算的秘密。

Oracle数据库作为复杂运算的首选数据库,其首先是通过所谓的数据高速缓存来实现对数据的高速运算与操作的。


数据高速缓存跟操作系统的缓存类似,其存储最近从数据文件中读取的数据块,其中的数据可以被所有的用户所访问。如当我们利用Select语句从数据库中查询员工信息的时候,其首先不是从数据文件中去查询这个数据,而是从数据高速缓存中去查找,而没有这个必要再去查询磁盘中的数据文件了。只有在数据缓存中没有这个数据的时候,数据库才会从数据文件中去查询。Oracle数据库为什么要如此设计呢?这是由于数据库在读取数据的时候,读取内存的速度比读取磁盘的速度要快很多倍,所以这种机制可以提高数据的整体访问效率。


虽然其他数据库也有这方面的设计,但是,相对来说,Oracle数据库比其他数据库,在这方面有更加出色的表现。难怪Oracle数据库在内存的要求上,比其他数据库要高。若以稍微的代价牺牲一些内存,而换取更高的数据访问性能。笔者认为还是值得的。下面我们就来看看,Oracle数据库在数据高速缓存上有哪些特殊的表现。


一、 空闲缓存块


当我们重新启动数据库后,系统就会为数据库分配一些空闲的缓存块。空闲缓存块中是没有任何数据的,他在那边默默的等着别写入记录。当Oracle 数据库从数据文件中读取数据后,数据库就会寻找是否有空闲的缓存块,以便将数据写入其中。


一般来说,数据库在启动的时候,就会在内存中预先分配这些缓存块。所以,Oracle数据库在启动的时候,会占用比较多的内存。但是,这可以免去在实际需要时向内存申请的时间。所以,有时候Oracle数据库虽然已启动,内存的占用率就很高,但是,其后续仍然可以正常运行的原因。而其他数据库虽然刚启动的时候内存占用率不是很高,但是,但系统内存到达80%以上时,在进行数据处理就会受到明显的影响。


所以,当我们利用SELECT语句从数据库文件中读取文件的时候,数据库首先会寻找是否有空闲的缓存。


二、命中缓存块


当SELECT语句先从数据库文件中读取数据后,会把取得的数据放入到这个命中缓存块中。也就是说,当我们利用查询语句从数据库查询处员工信息后,这个信息就会被保存在高速缓存中。直道高速缓存消耗完毕等原因,这个空间才会被释放。如此的话,下次用户在查询员工信息的时候,就不需要从数据库文件中再次查询相关信息,而直接从数据高速缓存中提取数据,从而提高数据库的访问效率。


另外要注意的一个问题是,命中缓存块中的数据不会被写入数据文件。确实,这个命中缓存块中的数据没有被更改,其当然也不会被写入数据库文件中。


三、脏缓存块


当我们利用SELECT查询语句把员工信息的数据查询出来后,数据库会把这个数据所存储的空缓存块做标记,表示该缓存块已经存有数据,使命中缓存块。此时,我们若在利用数据更新语句UPDATE对其中某条记录进行更新时,如要把张三的名字改为张四。运行UPDATE语句后,数据库也首先从高速缓存中查找是否有这条记录,若存在这条记录的话,就直接更改这条记录,并且把该缓存块标记为赃缓存块。如此的话,就可以保持数据的一致性。


也就是说,脏缓存块存储的是已经被修改过的,但是还没有写入到数据库文件的信息。当SQL的UPDATE等数据更新语句对某个缓存块中的数据进行更改之后,这个命中缓存块就会被数据库标记为脏缓存块。当满足一定的条件时,这些脏缓存块中的数据内容会被写入到数据库文件中去,以便永久性的保留数据库修改记录。


当系统中没有空闲缓存块,而用户又需要查询数据时,数据库就查询当前所有的脏缓存块,把最先更改的脏缓存块中的内容先写入数据库文件中,以便释放这个脏缓存块。数据库就又会把这个脏缓存块标记为空闲缓存块,以方便用户下次存入数据。


那Oracle数据库到底是通过什么手段,来控制空闲缓存块、命中缓存块、脏缓存块之间的相互转换的呢?说出来也许你不相信,Oracle数据库就是通过两张表,来管理这么复杂的功能。这两张表分别是DIRTY列表与LRU列表。


其中LRU列表保存着所有空闲缓存块、命中缓存块已经还没有被移入到DIRTY列表中的脏缓存块。当Oracle数据库用户在查询数据的时候,可能会遇到如下情况:


1、当用户查找员工信息时,数据库首先在LRU列表中查询是否有空闲缓存块。其查询的数据是从尾部开始查找。当查找有空闲的缓存块时,数据库就会把查到的数据写入到这个空闲缓存中。


2、若数据库在查询的时候,首先查到的是脏缓存的话,则会把这个脏缓存移动到DIRTY列表中,然后再继续查询,直到查询到合适的空闲缓存块为止。


3、若数据库在LRU列表中,从尾到头查了一遍,没有找到空闲缓存块,或者虽然有空闲缓存块,但是其容量不符合要求时,数据库就会暂时结束这一次查找。然后,系统就会触发数据库写进程,把DIRTY列表中的脏缓存块写入到数据库中去。已经被写入到数据库文件中去的脏缓存块将又被数据库标记为空闲缓存块,并插入到LRU列表中。当数据库执行完毕这个动作之后,数据库又会对LRU列表进行搜索,找到合适的数据高速空闲缓存之后,就会把读取的数据写入到这个空闲缓存中。所以,我们在利用数据库的时候,会发现有时候读取大量数据的时候,速度会比较慢。除了其他原因外,也有一部份原因是因为数据库没有查到足够大的空闲缓存在存放这些数据,故只好写进行读写操作,以释放更多的脏缓存,然后再进行查询操作。


知道了这些数据库高速缓存工作原理之后,我们数据库管理员又该做些什么呢,来对Oracle数据库进行优化。为此,笔者有以下建议:


1、为Oracle数据库配置尽量大的内存。Oracle数据库最新版本,根据官方的建议,其内存需要1G。虽然在低于这个内存数量的时候,数据库仍然可以运行,但是,其运行适度会大打折扣。当查询大量数据的时候,更是比较吃力。笔者现在使用的数据库服务器,是使用了4个G的内存。以前我用的是2个G的。内存升级后,发现数据库的性能得到了比较大的改善。


2、在对数据进行查询操作时,尽量使用限制条件。如现在需要查询销售部门的员工信息时,我们不需要查询全部的员工信息,而是在SELECT语句中,利用WHERE条件语句设置查询条件。如此的话,就可以充分利用DIRTY列表中的空闲缓存块,而不会因为空闲缓存块容量不够而频繁的去执行数据库写操作。这会明显降低数据库的运行操作。同时,在查询时,最好也能够明确查询的信息,如你只需要员工的姓名与入职日期,那就不需要把员工的出生年月、身份证号码都查询出来。所以,有时候合理设计视图,也可以提高数据库的运行效率。


3、最好不要在数据库服务器上运行其他的服务。在数据库服务器中,若还运行其它服务器的话,除了硬件资源争夺影响服务器的运行效率之外,还会产生一个问题。就是会使得数据库的数据高速缓存块不连续。这会直接影响数据库查询空闲缓存块的效率。对脏缓存块进行数据库写入操作以及数据库进行标记之间的转换也会产生影响。所以,根据笔者的经验,数据库服务器最好能够独立。最多只能跟其对应的应用服务器部署在同一台服务器上。如现在Oracle数据库是一台ERP系统的后台数据库,最好数据库能够跟ERP服务器分开部署。但是,若由于服务器资金的限制,那么可以把ERP应用服务器跟数据库服务器部署在一台服务器上。但是,不能再跟邮件服务器等应用服务器放在一起。这会影响数据高速缓存的管理效率,从而最终影响数据库的运行效能。现在服务器价格逐渐下滑,服务器的成本已经不是影响企业数据库应用的关键。所以,出于数据库性能考虑,笔者认为,企业在这上面还是应该大方的进行投资。没必要为了这么一点点钱,影响到数据库的性能。