分区(oracle 9i&10g学习)

分区概述
分区有利于管理非常大的表和索引,它使用了一种“分而治之”的逻辑。分区引入了一种分区键(partition key)的概念,分区键用于根据某个区间值(或范围值)、特定值列表或散列函数值执行数据的聚集。如果让我按某种顺序列出分区的好处,这些好处如下:

(1) 提高数据的可用性:

这个特点对任何类型的系统都适用,而不论系统本质上是OLTP还是仓库系统。可用性的提高源自于每个分区的独立性。对象中一个分区的可用性(或不可用)并不意味着对象本身是不可用的。优化器知道有这种分区机制,会相应地从查询计划中去除未引用的分区。在一个大对象中如果一个分区不可用,你的查询可以消除这个分区而不予考虑,这样Oracle就能成功地处理这个查询

(2) 减少管理负担:
之所以能减少管理负担,这是因为与在一个大对象上执行操作相比,在小对象上执行同样的操作从本质上讲更为容易、速度更快,而且占用的资源也更少。

由于从数据库中去除了大段,相应地减轻了管理的负担。在一个100GB的表上执行管理操作时(如重组来删除移植的行,或者在“净化”旧信息后回收表左边的“空白”空间),与在各个10GB的表分区上执行10次同样的操作相比,前者负担要大得多。另外,通过使用分区,可以让净化例程根本不留下空白空间,这就完全消除了重组的必要!

假设数据库中有一个10GB的索引。如果需要重建这个索引,而该索引未分区,你就必须将整个10GB的索引作为一个工作单元来重建。尽管可以在线地重建索引,但是要完全重建完整的10GB索引,还是需要占用大量的资源。至少需要在某处有10GB的空闲存储空间来存放两个索引的副本,还需要一个临时事务日志表来记录重建索引期间对基表所做的修改。另一方面,如果将索引本身划分为10个1GB的分区,就可以一个接一个地单独重建各个索引分区。现在只需要原先所需空闲空间的10%。另外,各个索引的重建也更快(可能是原来的10倍),需要向新索引合并的事务修改也更少(到此为止,在线索引重建期间发生的事务修改会更少)。

(3) 改善某些查询的性能:

主要在大型仓库环境中有这个好处,通过使用分区,可以消除很大的数据区间,从而不必考虑它们,相应地根本不用访问这些数据。但这在事务性系统中并不适用,因为这种系统本身就只是访问少量的数据。

(4) 可以把修改分布到多个单独的分区上,从而减少大容量OLTP系统上的竞争:如果一个段遭遇激烈的竞争,可以把它分为多个段,这就可以得到一个副作用:能成比例地减少竞争。

表分区机制
区间分区:
指定应当存储在一起的数据区间。例如,时间戳在Jan-2005内的所有记录都存储在分区1中,时间戳在Feb-2005内的所有记录都存储在分区2中,依此类推。这可能是Oracle中最常用的分区机制。
假设你想像刚才一样,将2005年和2006年的日期分别聚集到各自的分区,但是另外你还希望将所有其他日期都归入第三个分区。利用区间分区,这可以使用MAXVALUE子句做到这一点,如下所示:
CREATE TABLE range_example( range_key_column date,data varchar2(20))
PARTITION BY RANGE (range_key_column)
(PARTITION part_1 VALUES LESS THAN (to_date('01/01/2005','dd/mm/yyyy')), --第一分区
 PARTITION part_2 VALUES LESS THAN (to_date('01/01/2006','dd/mm/yyyy')) --第二分区
 PARTITION part_3 VALUES LESS THAN (MAXVALUE)--- 其他的第三分区)

这让我想起了新浪微博的架构

散列分区:

指在一个列(或多个列)上应用一个散列函数,行会按这个散列值放在某个分区中。
CREATE TABLE hash_example ( hash_key_column date,  data varchar2(20))
PARTITION BY HASH (hash_key_column)
( partition part_1 tablespace p1, partition part_2 tablespace p2 )
对一个表执行散列分区(hash partitioning)时,Oracle会对分区键应用一个散列函数,以此确定数据应当放在N个分区中的哪一个分区中。 Oracle建议N是2的一个幂(2、4、8、16等),从而得到最佳的总体分布。
使用散列分区,你将无从控制一行最终会放在哪个分区中。Oracle会应用散列函数,并根据散列的结果来确定行会放在哪里。如果你由于某种原因希望将某个特定行放在分区PART_1中, 就不应该使用散列分区
从某种程度上讲,散列分区对于提高可用性也很有用,临时丢掉一个散列分区,就能访问所有余下的分区。 也许有些用户会受到影响,但是很有可能很多用户根本不受影响,但是很有可能很多用户根本不受影响。另外,恢复的单位现在也更小了。你不用恢复一个完整的大 表;而只需恢复表中的一小部分。最后一点,散列分区还有利于存在高度更新竞争的环境。我们可以不使一个段“很热”,而是可以将一个段散列分区为16个“部分”,这样一来,现在每一部分都可以接收修改。

列表分区:

是Oracle9i Release 1的一个新特性,指定一个离散值集,来确定应当存储在一起的数据。例如,可以指定STATUS列值在(’A’,’M’,’Z’)中的行放在分区1中,STATUS值在(‘D’,’P’,’Q’)中的行放在分区2中,依此类推。
create table list_example ( state_cd varchar2(2), data varchar2(20))
 partition by list(state_cd)
( partition part_1 values ( 'ME', 'NH', 'VT', 'MA' ),partition part_2 values ( 'CT', 'RI', 'NY' ),part_3 values ( DEFAULT )  --其他分区)
与区间分区主要区别:区间有明显的临界的概念如<某个时间值。

组合分区:

这是区间分区和散列分区的一种组合,或者是区间分区与列表分区的组合。通过组合分区,你可以先对某些数据应用区间分区,再在区间中根据散列或列表来选择最后的分区,顶层分区机制总是区间分区。第二级分区机制可能是列表分区或散列分区。

行移动
1:修改不会导致使用一个不同的分区;行仍属于原来的分区。这在所有情况下都得到支持。
2:修改会导致行跨分区移动。只有当表启用了行移动时才支持这种情况;否则,会产生一个错误。
简而明之:原来数据在分区1,update过后在分区2,导致了行移动。语法:alter table range_example enable row movement
行移动会产生rowid改变。

索引分区

随表对索引完成相应的分区:这也称为局部分区索引(locally pertitioned index)。每个表分区都有一个索引分区,而且只索引该表分区。一个给定索引分区中的所有条目都指向一个表分区,表分区中的所有行都表示在一个索引分区中。

按区间对索引分区:这也称为全局分区索引(globally partitioned index)。在此,索引按区间分区(或者在Oracle 10g中该可以按散列分区),一个索引分区可能指向任何(和所有)表分区。

分区与性能:
对系统应用分区来“提供性能”之前, 先要确保自己真正了解系统需要什么。如果系统目前是CPU密集的(占用大量CPU时间),但是CPU的使用并不是因为竞争和闩等待,那么引入分区并不能使问题好转,而只会让情况变得更糟糕!
一般来讲,对于OLTP中的数据获取,分区确实没有正面的影响;相反,我们还必须小心地保证数据获取不要受到负面的影响。但是对于高度并发环境中的数据修改,分区则可能提供显著的好处。

考虑一个相当简单的例子

有一个表,而且只有一个索引,在这个表中再增加一个主键。如果没有分区,实际上这里只有一个表:所有插入都会插入到这个表中。对这个表的freelist可能存在竞争。另外,OBJECT_ID列上的主键索引是一个相当“重”的右侧索引。假设主键列由一个序列来填充;因此,所有插入都会放到最右边的块中,这就会导致缓冲区等待。另外只有一个要竞争的索引结构T_IDX。目前看来,“单个”的项目太多了(只有一个表,一个索引等)。

再来看分区的情况。按OBJECT_ID将表散列分区为16个分区。现在就会竞争16个“表”,而且只会有1/16个“右侧”,每个索引结构只会接收以前1/16的工作负载,等等。也就是说,在一个高度并发环境中可以使用分区来减少竞争。不过必须注意,与没有分区相比,数据的分区处理本身会占用更多的CPU时间。也就是说,如果没有分区,数只有一
个去处,但有了分区后,则需要用更多的CPU时间来查明要把数据放在哪里。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值