如何在oracle pl/sql中批量更新大型表,以避免耗尽空间?
我有一张很大的桌子。我试图用随机字母数字混淆表中每个记录的VARCHAR2列。我的过程在较小的数据集上成功执行,但它最终将在我无法控制其设置的远程数据库上使用,因此我希望成批执行UPDATE语句以避免耗尽空间 是否有某种我可以启用的选项,或者一种标准的方法来进行分块更新如何在oracle pl/sql中批量更新大型表,以避免耗尽空间?,oracle,plsql,Oracle,Plsql,我有一张很大的桌子。我试图用随机字母数字混淆表中每个记录的VARCHAR2列。我的过程在较小的数据集上成功执行,但它最终将在我无法控制其设置的远程数据库上使用,因此我希望成批执行UPDATE语句以避免耗尽空间 是否有某种我可以启用的选项,或者一种标准的方法来进行分块更新 我要补充的是,记录中没有任何未被混淆的显著特征,因此我认为在循环中使用rownum的想法是行不通的。我通过将主键映射到整数mod n来实现这一点,然后对每个x执行更新,其中0如果要更新表中的每一行,最好按照Select创建一个表
我要补充的是,记录中没有任何未被混淆的显著特征,因此我认为在循环中使用rownum的想法是行不通的。我通过将主键映射到整数mod n来实现这一点,然后对每个x执行更新,其中0如果要更新表中的每一行,最好按照Select创建一个表,然后删除/截断原始表并用新数据重新追加。如果您有分区选项,那么可以将新表创建为具有单个分区的表,并简单地将其与EXCHANGE分区交换 插入所需的撤消操作要少得多,使用NOLOGING/+APPEND/hint的直接路径插入也不会产生太多的重做操作
无论采用哪种机制,都可能存在旧值的“取证”证据,例如由于行移动而保留在撤消中或分配给表的可用空间中。以下内容未经测试,但应有效:
declare
l_fetchsize number := 10000;
cursor cur_getrows is
select rowid, random_function(my_column)
from my_table;
type rowid_tbl_type is table of urowid;
type my_column_tbl_type is table of my_table.my_column%type;
rowid_tbl rowid_tbl_type;
my_column_tbl my_column_tbl_type;
begin
open cur_getrows;
loop
fetch cur_getrows bulk collect
into rowid_tbl, my_column_tbl
limit l_fetchsize;
exit when rowid_tbl.count = 0;
forall i in rowid_tbl.first..rowid_tbl.last
update my_table
set my_column = my_column_tbl(i)
where rowid = rowid_tbl(i);
commit;
end loop;
close cur_getrows;
end;
/
这并不是最有效的——一次更新就可以了——但它会使用ROWID进行更小的、用户可调的批处理。如果我必须更新数百万条记录,我可能会选择不更新 我更可能创建一个临时表,然后从旧表中插入数据,因为insert不会占用大量的重做空间,而且执行的撤消操作更少
CREATE TABLE new_table as select <do the update "here"> from old_table;
index new_table
grant on new table
add constraints on new_table
etc on new_table
drop table old_table
rename new_table to old_table;
您可以使用并行查询来实现这一点,不记录大多数操作会生成非常复杂的结果
几乎不需要重做,也不需要撤消—只需更新数据库所需时间的一小部分
数据 如果想要大小不同的集合,应该使用NTILE分析函数;ORA_散列可能具有不可预测的值,尤其是当使用的值不是要散列到的存储桶数的2次方时。ORA_HASHn,3可以有4个值,所以您的示例可能会错过更新大约1/4的数据。Adam:请注意,我使用的是MODORA_HASHID,3,而不是ORA_HASHID,3。我故意使用MOD,因为ORA_散列的额外参数令人困惑。谢谢你的推荐。我还不完全熟悉分析。@adam musch:试图在WHERE中使用NTILE给了我一个错误:ORA-30483:不允许使用窗口函数here@Greg,则必须嵌套查询,就像where子句中使用的所有分析函数一样。请参见此处-别忘了禁用引用表的外键约束。似乎此查询的相同答案可能仍然会生成太旧的ORA-01555快照。可能是因为在提交之间进行抓取
CREATE TABLE new_table as select <do the update "here"> from old_table;
index new_table
grant on new table
add constraints on new_table
etc on new_table
drop table old_table
rename new_table to old_table;