Oracle SQL -删除不记录的行



我将在每个批处理中删除数百万行,由于行太多,我无法将它们一起删除。我想删除行没有日志,但我没有找到任何东西。有人可以帮我写一个删除无日志查询吗?

我的查询是这样的:

DELETE
FROM MyTable
WHERE TO_CHAR(MyDate, 'YYYYMM') = 202101

即使我只考虑一个月(大约600万条记录),我也无法删除它们

删除操作总是logging,并且还需要大量的undo,这就是为什么当涉及大量行时,它们在性能方面可能会很昂贵。此外,如果您有索引,那么也必须删除那里的行。

有几个选项,但它们很大程度上取决于您的环境。我会尝试两种方法

我使用并行度8。如果您的数据库服务器的CPU较少或较多,则可以使用度数。我不会在删除中使用太多的程度,但我会在选项2

中尽可能地使用选项1

alter session enable parallel dml ;
delete /*+parallel(a,8) */ from myTable a where TO_CHAR(MyDate, 'YYYYMM') = 202101 ;
commit;

选项2(使用CTAS和截断/插入)

alter session enable parallel dml;
alter session enable parallel ddl;
create table MyBkpTable parallel compress nologging pctfree 0 
as select /*+parallel(a,8) */ * from MyTable a 
where TO_CHAR(MyDate, 'YYYYMM') != 202101 ;
truncate table MyTable reuse storage ;
insert /*+append parallel(a,8) */ into MyTable a 
select /*+parallel(b,8) */ * from MyBkpTable b;
commit;

如果表上有很多索引,将所有索引标记为不可用,并在运行插入追加之前使用alter session set skip_unusable_indexes=true。最后,重建所有索引。

当表被分区时,为了从partition pruning中获益,您可以使用(,只要分区键是MyDate)

delete /*+parallel(a,8) */ from myTable a where MyDate >= date '2021-01-01' and MyDate < date '2021-02-01' ;

或者更好,直接截断所有的分区

alter table myTable truncate partition <<partition_name>>

最新更新