删除分区
你可以从范围、间隔、列表或者复合[范围|列表]分区表中删除分区。对于间隔分区表而言,你只能删除范围分区或者那些已经物化的间隔分区。对于哈希分区表或者复合哈希分区表的哈希子分区而言,你必须使用融合操作来代替。
你不能从引用分区表中删除一个分区。相反,对父表的删除操作会级连到所有子表。
删除表分区
使用一下语句来删除一个表分区或者子分区:
- ALTER TABLE ... DROP PARTITION,用来删除一个表分区
- ALTER TABLE ... DROP SUBPARTITION,用来删除一个复合[范围|列表]分区表的一个子分区
为了保存分区里的数据,可以使用合并分区语句来代替删除分区语句。
如果该表定义有本地索引,那么上述语句将会从本地索引中删除对应的分区或子分区。所有的全局索引,或者全局分区索引的所有分区都将被标识为UNUSABLE,除非符合下面两个条件之一:
- 你指定了UPDATE INDEXES子句(不能用来指定索引组织表,可以使用UPDATE GLOBAL INDEXES来代替)
- 删除的分区或者子分区为空
注意:
如果一个表只包含一个分区,你不能删除该分区。相反,你必须删除这个表。
在间隔分区表或者间隔复合分区表的范围分区部分,你不能删除最高的范围分区。
下面的部分包含了删除表分区的一些场景。
从一个包含数据和全局索引的表中删除一个分区
如果分区包含数据并且表上定义有一个或多个全局索引,那么可以使用下面任一方法来删除表分区。
方法一
在ALTER TABLE ... DROP PARTITION语句执行期间,保持全局索引不变。然后,你必须重建全部全局索引(无论是否分区),因为这个索引(或者索引分区)已经被标识为UNUSABLE。下面的语句提供了一个示例,首先从sales表删除分区dec98,然后重建该表的全局索引。
ALTER TABLE sales DROP PARTITION dec98;
ALTER INDEX sales_area_ix REBUILD;
如果索引sales_area_ix是一个范围分区全局索引,那么索引的全部分区都需要重建。并且,我们不可能在一条语句中重建索引的所有分区。你必须针对索引的每一个分区分别执行REBUILD语句。下面的语句分别重建了索引分区jan99_ix, feb99_ix, mar99_ix, ..., dec99_ix。
ALTER INDEX sales_area_ix REBUILD PARTITION jan99_ix;
ALTER INDEX sales_area_ix REBUILD PARTITION feb99_ix;
ALTER INDEX sales_area_ix REBUILD PARTITION mar99_ix;
...
ALTER INDEX sales_area_ix REBUILD PARTITION dec99_ix;
该方法最适用于被删除分区包含总数据很大比例的大表。
方法二
在执行ALTER TABLE ... DROP PARTITION之前,执行DELETE语句来删除分区的所有数据行。DELETE语句更新全局索引。
例如,要删除第一个分区,执行以下语句:
DELETE FROM sales partition (dec98);
ALTER TABLE sales DROP PARTITION dec98;
该方法最适用于小表,或者被删除分区数据占总数据很小比例的大表。
方法三
在执行ALTER TABLE... DROP PARTITION语句时指定UPDATE INDEXES语句。这样做的话,在删除分区的同时也会更新全局索引。
ALTER TABLE sales DROP PARTITION dec98
UPDATE INDEXES;
从一个包含数据和引用完整性约束的表中删除一个分区
如果该表包含引用完整性约束,并且一个分区包含数据,选择下面一种方法来删除该分区。该表只有一个本地索引,因此不需要重建任何索引。
方法一
如果表中不含引用被删除分区中数据的数据,那么你可以禁用引用表的完整性约束,执行ALTER TABLE ... DROP PARTITION语句,然后在重新启用完整性约束。
该方法最适用于被删除分区包含总数据很大比例的大表。如果表中含有引用被删除分区中数据的数据,那么必须确保删除这些数据,这样你就可以重新启用引用完整性约束。
方法二
如果引用表中有数据,那么在你执行ALTER TABLE ... DROP PARTITION语句之前,你可以执行DELETE语句来删除分区的所有数据。DELETE语句会强制引用完整性约束,也会激发触发器并生成redo和undo日志。如果你创建约束时包含ON DELETE CASCADE选项,那么删除操作也会成功删除引用表的所有行。
DELETE FROM sales partition (dec94);
ALTER TABLE sales DROP PARTITION dec94;
该方法最适用于小表,或者被删除分区数据占总数据很小比例的大表。
删除间隔分区
你可以删除一个间隔分区表中的间隔分区。该操作只会删除分区的数据,分区的定义会被保留。如果有数据插入到刚刚被删除的分区,那么数据库将会再次创建一个间隔分区。
你也可以删除一个间隔分区表中的范围分区。在一个间隔分区表中删除一个范围分区,要遵守在一个范围分区表中删除一个范围分区的规则。如果你要删除范围分区靠中间的分区,那么下一分区的下边界将会移动到你刚刚删除的那个分区的下边界。你不能删除一个间隔分区表中范围分区部分的最高范围分区。
下面的例子删除了sales表的2007年九月的间隔分区。由于该标只有本地索引,没有索引失效。
ALTER TABLE sales DROP PARTITION FOR(TO_DATE('01-SEP-2007','dd-MON-yyyy'));
删除索引分区
你不能显式地删除一个本地索引的一个分区。相反,只有你删除基表的一个分区时相应的本地索引分区会被删除。
如果一个全局分区索引为空,那么你可以通过执行ALTER INDEX ... DROP PARTITION语句显式地删除索引分区。但是,如果一个全局索引分区不为空,那么删除这个分区将会导致下一个最高分区被标识为UNUSABLE。例如,你要删除索引分区P1,P2时下一个最高分区。你必须执行以下语句:
ALTER INDEX npr DROP PARTITION P1;
ALTER INDEX npr REBUILD PARTITION P2;
注意:
在一个全局索引中,你不能删除最高分区。
: