ORA-14402: 更新分区关键字列将导致分区的更改

2015-02-25 15:02:41 · 作者: · 浏览: 35

alter table xxx enable row movement;


? ? 之后就可以成功update 分区字段,同时因为行的物理移动,导致rowid发生变化,对应列值的索引叶块 会标记为删除,插入新的叶块,重定义完分区后,记得关闭行移动。


alter table xxx disable row movement;


下面三种情况需要开启row movement
? ? ? 1.更新Partition Key
? ? ? 分区表某一行更新时,如果更新的是分区列,并且更新后的列值不属于原来的这个分区,如果开启了这个选项,就会把这行从这个分区中delete掉,并加到更新后所属的分区。相当于一个隐式的delete+insert,但是不会触发insert/delete触发器。如果没有开启这个选项,就会在更新时报错ORA-14402;
? ? ? 这一操作产生影响的特殊之处在于这是个DML操作,是和online transaction密切相关。对于这样一个UPDATE,实际上分为3步:先从原有分区将数据删除;将原数据转移到新分区上;更新数据。
? ? ? 其影响就在于以下几个方面:
一个UPDATE被分解为DELET、INSERT、UPDATE三个操作,增加了性能负担。其中,DELETE的查询条件与原UPDATE的查询条件相同,新的UPDATE的查询条件是基于INSERT生成的新的ROWID,相应的Redo Log、Undo Log会增加;
? ? ? 如果Update语句还涉及到了Local Index的字段的话,新、旧2个分区上的Local Index都要被更新。
? ? ? 还有一点,Row Movement会和域索引(Domain Index)产生冲突:如果表上定义了域索引,开启Row Movement就会失败;反之亦然。


? ? 2. Flaskback table to 某时间
? ? ? ? Flashback Table实际是通过Flashback Query将表中数据进行了一次删除、插入操作,因此ROWID会发生变化
? ? 3. Shrink Segment
? ? ? ? Shrink Segment能帮助我们压缩数据段、整理数据碎片、降低高水位,以提高性能、节省空间。


? ? 有必要说明一下,row movement并不是行迁移,最大的区别是行迁移的rowid是不变的,行迁移是update 行记录时,数据块没有足够的空闲容纳数据行,Oracle将此行移到其他数据块,同时保留此行的rowid不变,并在原数据块建一指针指向新的行位置。这种情况下,读取一行数据就会访问2个数据块,增加IO,导致性能下降。


如果直接创建主键,使用的global index,当某分区被drop后,主键会失效,


ALTER TABLE PHAECDA1.HCPSGLSINFOPZOW_NEW ADD CONSTRAINT PK_STAMP PRIMARY KEY(T_STAMP) tablespace xx;


改为 local index,但不包含分区段,报错


ALTER TABLE PHAECDA1.HCPSGLSINFOPZOW_NEW ADD CONSTRAINT PK_STAMP PRIMARY KEY(T_STAMP) using index local tablespace? xxx;


ORA-14039: partitioning columns must form a subset of key columns of a UNIQUE


ORA-14039: 分区列必须构成 UNIQUE 索引的关键字列子集


Local index ,主键+分区键? 作为新的主键,自动创建分区index ,index会按分区段Partition 分区到table的分区表空间


ALTER TABLE PHAECDA1.HCPSGLSINFOPZOW_NEW ADD CONSTRAINT PK_STAMP PRIMARY KEY(T_STAMP,CLDATE) USING INDEX LOCAL;


?先创建index ,再创建主键,


当然,主键也可直接作为分区段