默认情况下,oracle的分区表对于分区字段是不允许进行update操作的,如果有对分区字段行进update,就会报错——ORA-14402: 更新分区关键字列将导致分区的更改。這種情況可以通過開啟表的行移動來允許對分區字段的update 操作:
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 ,再創建主鍵,
當然,主鍵也可直接作為分區段