三个提高Oracle处理大量数据效率的有效途径

Oracle性能话题涉及面非常广,市场上有很多书籍专门介绍Oracle调优。对性能的追求是无止境的,需要长期不懈的努力;但要避免性能成为问题却不难,甚至可以说很简单。本文从简单实用的角度出发,给出几个提高Oracle处理大量数据效率的有效途径。

 

一、配置数据库初始化参数

 

 

数据库的全部初始化参数可以在OEM中看到。参见下图:

 

 

 

在新建一数据库时,如果不配置这些初始化参数,Oracle会给这些参数以默认值。当数据库规模不大时,采用Oracle的默认值通常不会遇到性能问题。下面介绍对处理大量数据效率有“举足轻重”影响,并且,默认值会带来性能问题的几个参数:

 

1) db_block_size

 

 

该参数设置了Oracle进行一次I/O的基本单位——数据库块的大小 (以字节计)。毫不夸张的说,该参数对于大数据量处理是最重要的一个参数。该参数值设置的越大,对大数据量处理越有利。受操作系统所限,NT4最大只能设置为8KWin2k最大只能设置为16KOracle本身允许的最大值是64K。忘了说了,db_block_size应设置为2的幂。

 

对于分析型数据库,设置为32K是不错的选择。对于OLTP系统,笔者没有多少经验,网上的说法是设置8K是个比较好的平衡点。Oracle是有许多“神话”的,8K的说法未必符合现在的软硬件情况,更未必符合我们企业的实际情况。如果有时间有机会,比较一下8K好还是16K好总是不会错的。

 

db_block_size是最基本的一个参数,也是最容易被忽视的一个参数。该参数只能在创建数据库时设置,此后不能更改;一旦有所失误,只能通过重建数据库的方法补救。因此,您建库时应当慎重考虑该参数。

 

2

db_file_multiblock_read_count

 

Oracle官方的说明:在涉及一个完全连续扫描的一次 I/O 操作过程中读取的块的最大数量。对于大的查询来说,进行全表扫描往往比使用索引效率高很多。全表扫描操作是典型的“完全连续扫描”。如果db_block_size设置为32Kdb_file_multiblock_read_count设置为8;则一次I/O操作最多可以连续读8个数据库块,即256K

 

 

db_file_multiblock_read_count并非越大越好。对于数据分析系统,db_file_multiblock_read_countdb_block_size的乘积为256K足够了。对于建立在Unix上的OLTP系统,根据网上的说法,二者的乘积为64K是不错的选择。

 

根据笔者的经验,让数据连续分布在物理磁盘上比考量该参数更加有效。

 

3) sort_area_size

 

 

sort_area_size的重要性可以说是和db_block_size并列的。该参数指出数据库执行一个查询时最多可以使用多大内存来排序。受系统资源所限,我们无法将该参数设置太大。特别是当我们采用独立模式建库时,每个Session都可能会申请一个或多个排序空间。如果我们设置sort_area_size8M,同时登上来100个用户并发查询,则可能会占去800M内存甚至更多。当主存不够用时,就要用虚拟内存了。如果Oracle被迫使用虚拟内存,则数据库的性能将急剧下降。

 

对于该参数的设置,网上有人建议至少应超过用于排序记录数的平方根。也就是说,对100万条记录进行排序,每条记录占用1K空间,则sort_area_size至少应设置为1M。对1000万条记录进行排序,每条记录占用1K空间,sort_area_size设置为4M应该够用了。

 

根据上述数字,OLTP系统的sort_area_size不妨设置为1M2M;数据分析系统的sort_area_size不妨设置为4M8M

 

db_file_multiblock_read_countsort_area_size在数据库建立好以后是可以修改的。修改方法很简单。搜索Oracle的安装目录,找到PFILE文件夹(可能会找到多个,其父目录的名字会给我们提示),里面有一个init文本文件,照着里面的内容修改就可以了(找不到相关参数就自己加一个)。修改完毕后重启数据库方能生效。Oracle9i以上版本可以做到不用重启数据库,本文就不介绍了。

 

二、编写高效的SQL

 

 

 

一般说来,看起来简单的SQL通常都不会遇到性能问题。SQL的执行效率通常比程序的执行效率要高。因此,尽量用SQL解决问题和尽量用简单的SQL解决问题应当是我们开发的指导原则。

 

编写高效的SQL需要一定的基本功。本文不讨论SQL的理论基础。本文仅介绍一个有用的技术:人为干预SQL的执行计划。当SQL较复杂时,执行计划的可能性会非常多。用最短的时间选择一个最优的执行计划是Oracle奋斗的目标。Oracle数据库有相关的参数来调整挑选执行计划的算法,这些参数本文不讨论,有兴趣的读者可以自己上网去搜。

 

所谓“人为干预SQL的执行计划”实际上是提示Oracle如何去挑选最优的执行计划。SQL提示的语法很简单:用“/*+”和“*/”将提示包括起来,中间写上关键字就可以了。SQL:提示的关键字有很多,下面介绍几个典型的关键字,更多的用法可以自己上网搜。

 

1)指定全表扫描:

 

SELECT /*+FULL(table_name)*/ field1,field2

 

 

FROM table_name;

 

 

一个大查询如果用到了一个大表中相当一部分的数据,则采用全表扫描的执行计划会比采用索引的执行计划效率高很多。

 

2)数据直接插入到表的最后,可以提高速度:

 

INSERT /*+append*/

 

 

INTO table_name

 

 

select * from table_name1;

 

 

Oracle中很多数据块因为曾经做过delete操作而有空闲空间,如果使用append关键字,则Oracle不会去寻找这些有空闲空间的数据块,从而提高了insert语句的执行速度。需注意append关键字只适合于大数据量插入。

 

三、分区

 

 

分区技术相对前面介绍的技术而言要复杂一些。分区实际上是据根据某(些)个字段在物理上将一个大表的数据分开存储,从而,能提高我们查询的效率,同时也能加强我们对数据的管理。典型例子的是根据日期字段分区,从而,当我们查询某个时期的数据时,只需要扫描某个分区的数据而不需要扫描整表的数据。

 

当我们决定采用分区技术时,只需要在create table语句以及create index语句中增加一些语法。一般的面向DBA的书籍都会有专门的章节介绍分区技术。这里不再赘述。

 

一个表是否被分区并不影响我们使用:对普通表的操作可以用在分区表上。相反,分区表增加了我们使用该表的灵活性,创建分区表后,我们可以使用Alter table命令来增加、删除、交换、移动、修改、重命名、划分、截断一个已存在分区的结构。一个典型的例子,如果用月份分区,我们可以使用truncate命令在瞬间删除某个月份的全部数据。

 

我们需要注意的是在创建局部唯一索引时,索引字段应包括分区字段,否则会创建失败。创建全局索引则没有这样的限制。

 

 

 

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值