李永亮

(沈阳航空航天大学,辽宁 沈阳110136)

Oracle数据库被越来越多的应用在各个领域,信息系统的优劣与数据库系统的性能有着直接的关联。随着数据库规模的不断扩大,如何保持数据库应用系统高效地运行,受到人们越来越多的关注。对于应用系统来说,数据访问操作在整个系统中占据着相当大的比重,也就是说,数据访问速度的快慢直接影响着系统的性能。

1 影响查询优化器决策的因素

Oracle数据库引擎访问数据基本上有两种方式,一种是扫描整个表,一种是基于冗余访问结构(如索引)进行查找或基于表本身的机构(比如哈希聚簇)进行查找。查询优化器对于访问数据选用全表扫描还是索引扫描,基于对这两种访问方式相应开销的估算,影响优化器决策的因素主要有以下几个:

1)进行全表扫描需要读取的数据块数目。

2)进行索引查询需要读取的数据块数目,这主要基于对WHERE子句谓词返回的记录数目的估计。

3)进行全表扫描时多块读的相关开销以及为满足索引查询进行的单块读的开销。

4)内存缓存中的索引块和数据块数目的假设。

当查询优化器正确的选择执行计划后,并不意味着特定执行计划一定运行良好。所以有时可以通过调整SQL语句或访问结构,来达到优化的目的。判断数据访问最有效的标准是处理数据时消耗的资源最少,当然最有效不一定是最快。

2 影响数据访问的因素

一般对全表扫描和索引扫描来说,在WHERE子句的条件选择性不是很高时,全表扫描是最合适的检索路径,而在条件的选择性很高时,索引或聚簇方法将更合适。

其中影响索引的因素主要有缓存区高速缓存区的命中率、记录大小和数据的分布情况。索引检索有助于获得更高的高速缓存命中率;就IO而言,无论记录多大,索引访问的开销几乎是相同的,而记录越大,全表扫描必须读取的数据块就越多,代价越高。对于数据的分布,如果表中记录大体按照索引列的顺序存储,那幺索引访问需要更少的数据库并大大减少逻辑IO的开销。而对于全表扫描,如果需要访问表的所有或大部分记录的话,那幺全表扫描是最合适的方法。

3 全表扫描避免的优化

对于这两种访问方式的优化就是对于该使用索引的,却使用了全表扫描,而应该使用全表扫描的却使用了索引。因此对应的优化方法主要有两类,一类是让索引起到该起的作用,避免意外的表扫描,一类优化必要的全表扫描。

即使存在适当的索引或散列检索路径,由于SQL语句的写法,优化器也可能无法利用这些访问路径,因此避免意外的表扫描主要有以下几个原则及解决方法:

1)避免使用不等条件。如果使用不等条件,Oracle一般不会使用索引,因此如果认为某个查询使用索引更加高效,那幺请使用IN、OR或>来重写查询。

2)空值查询。当索引中列的数据都为空值时,B*树索引中的条目将不会创建,因此不能使用某列的B*树索引查找空值,而应该将列定义成非空并设置默认值,而后用默认值检索。

3)在列上使用函数或表达式而无意中禁用了索引,因此应避免在WHERE子句中的索引列应用函数或操作,而是在与索引进行比较的值上应用函数或操作。

4)对于无法避免在索引列使用函数或表达式是,可以考虑使用基于相同函数或表达式的函数索引。

5)对于多列查询可以对多列使用组合索引或使用多个索引合并。

6)利用Oracle的统计信息或创建虚拟列等技术,帮助优化器做出精确的估算,从而更准确的选择出数据的访问方式。

4 全表扫描的优化

以上讨论的避免全表扫描的方法并不总是能获得最优的访问,尤其是访问表的大部分数据时,更是如此。有许多的全表扫描优化技术,主要的几个技术包括:

1)通过让表变小来减少扫描所需要的逻辑读取的数量。通过提高数据库IO的效率降低扫描所需要的物理块读取的数量。

2)通过缓存或抽样降低扫描的开销。

3)通过使用并行查询选项为扫描分配更多的资源。

4)执行快速的全索引扫描来代替全表扫描。

5)对表进行分区,只读取所选择的分区。

特别需要注意的是,完成全表扫描的工作数量主要取决于需要扫描的数据块数量,因此也有很多有效的方法来减少扫描的数据块数量,主要有以下四种方式:

1)通过重建表来降低高水位线。当需要进行全表扫描时,Oracle会去读取从第一个被分配的块到曾经包含数据的最高那个块之间的每一个块。因此如果一张表上经常发生大量的删除操作,高水位线将比实际需要的位置更高,每块里的记录条数减少,检索时IO的开销就会增加。

2)通过修改PCTFREE和PCTUSED参数来向每个块里放入更多的记录。该方法由于自动段存储管理的广泛使用,而现在几乎没有意义,但是对使用早期的数据库版本来说有一定的作用。

3)减少记录的长度,可能是通过将大的且并不常访问的列迁移到独立的表中。如果表经常进行全表扫描而且包含大量的不常访问的列,就可以将这些列迁移到其他的表中来减少需要扫描的块,尤其是很少访问的长列。

4)压缩表中的数据,压缩表也能生成更小的表,从而使扫描速度更快。

5 总结

大多数情况下,优化器会自动选择好数据的访问方式,但是当优化器不能选择最优的访问路径时或需要一个不同的访问路径,需要系统管理维护人员能够评估优化器的选择,并给出一个更优的访问路径,这就需要利用以上的优化方法如创建索引、聚簇或表分区等来影响优化器做出更正确的决策。

同时在索引访问和全表扫描之间没有通用的一个平衡点,如果需要访问表的所有或大部分记录,那幺全表扫描时最快的方式,如果从大表里检索一条记录,那幺基于该列的索引将提供更有效的访问路径,在这两个极端之间,要预见哪种方式更高效是很难的。

[1]Sam R.Alapati,Darl Kuhn,Bill Padfield.Oracle Database 11g性能优化攻略[M].朱浩波,译.北京:人民邮电出版社,2013:50.

[2]Christian Antognini.Oracle性能诊断艺术[M].童家旺,胡怡文,冯大辉,译.北京:人民邮电出版社,2009:269-274.

[3]Guy Harrison.Oracle性能优化求生指南[M].郑勇斌,胡怡文,童家旺,译.北京:人民邮电出版社,2012:197-209.

[4]李展涛,曹英忠.基于Oracle数据库的SQL语句优化[J].微型机与应用,2011,(21):11.

[5]赵新民,崔海.Oracle数据库SQL语句优化要点分析[J].信息安全与技术,2014,(6):65-66.