2

我有一个 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…)

当然,这会非常缓慢。

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

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

可能有人有另一个想法如何高效地解决这个问题?

PS:我使用 ORACLE 11g 作为数据库。PPS:对不起我的英语不好......

4

2 回答 2

3

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

我不认为对一个分区如此之大的表进行更新实际上并没有那么糟糕。您可以轻松地将更新拆分为 8k 迷你更新(每个单独的小分区):

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

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

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

于 2013-08-23T16:25:20.460 回答
0

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

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

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

于 2014-04-07T10:06:12.490 回答