ORACLE 11g SET COLUMN NULL用于大表的特定分区

时间:2013-08-23 14:36:36

标签: sql oracle oracle11g

我有一个Composite-List-List分区表,其中包含19列和大约4亿行。每周一次在此表中插入新数据,在插入之前,我需要为特定分区将2列的值设置为null。

明显的方法类似于以下,其中COLUMN_1是分区标准:

UPDATE BLABLA_TABLE 
SET COLUMN_18 = NULL, SET COLUMN_19 = NULL 
WHERE COLUMN_1 IN (VALUE1, VALUE2…)

当然这会非常缓慢。

我的第二个想法是将CTAS用于我需要将这两列设置为null的每个分区,然后使用EXCHANGE PARTITION来更新我的大表中的数据。不幸的是,这不起作用,因为它是一个复合分区。

我可以对子分区使用相同的方法,但之后我必须使用CATS约8000次,然后每周删除这些表。我想这不会通过即将到来的代码审查。

愿有人知道如何正确解决这个问题吗?

PS:我正在使用ORACLE 11g作为数据库。 PPS:抱歉我的英语不好...... ..

2 个答案:

答案 0 :(得分:3)

您已经排除了通过DDL(切换分区)进行更新,因此我们只考虑DML。

我认为用表如此严重分区的更新实际上并不是那么糟糕。您可以轻松地将更新拆分为8k小型更新(每个小型分区):

UPDATE BLABLA_TABLE SUBPARTITION (partition1) SET COLUMN_18 = NULL...

每个子分区将包含15k行,平均更新,因此更新相对较小。

虽然它仍然代表着非常大量的工作,但它应该很容易设置为并行运行,希望在数据库活动非常轻的时候。如果其中一个失败(行锁定?),单个更新也很容易重启,而120M更新在发生错误时需要很长时间才能回滚。

答案 1 :(得分:0)

如果我要更新表中几乎90%的行,我会检查只是插入到具有相同结构的另一个表的可行性/持续时间(更少重做,没有行链接/迁移,旁路缓存等通过直接插入。首先删除索引和触发器。排除列以使其在目标表中保持为空),将表重命名为" swap"他们,重建索引和触发器,然后删除旧表。

根据我在数据仓库方面的经验,普通直接插入比更新/删除更好。需要更多步骤,但总体上花费的时间更短。我同意,当你必须处理大部分表时,分区交换说起来容易做起来,而对于ETL开发人员来说它更复杂(逻辑/算法绑定到物理层中的内容),我们没有&#39 ;到目前为止遇到需要进行分区交换。

我还会在自己的表空间中隔离此表,然后在这两个表空间之间交替存储(从第一个插入到第二个drop表,反之亦然,在下一次运行中,调整空表空间以回收空间)。