我有一个PL / SQL文件,一次需要删除整个表。挑战是:
截断表 无法使用,因为无法为相关数据库用户提供执行DDL命令的权限(由于SOX合规性)
< / LI>delete * 在表格记录数量较少的情况下效果很好。但是,该表可能有数百万条记录,在这种情况下,重做日志文件大小会急剧增加,从而导致性能问题
以下解决方案工作:
有没有更好更有效的方法来解决这个问题?
答案 0 :(得分:2)
如果重做日志文件大小有问题,您可以在每次删除后删除部分COMMIT。例如:
LOOP
--delete 1000000 records in each iteration
DELETE FROM tmp_test_table
WHERE 1=1--:WHERE_CONDITION
AND rownum <= 1000000;
-- exit when there is no more to delete
EXIT WHEN SQL%rowcount = 0;
COMMIT;
END LOOP;
答案 1 :(得分:0)
您可以使用以下几种方法: 使用分区:执行批量删除的最快方法是删除Oracle分区。 调整delete子查询:许多Oracle删除使用where子句子查询,优化子查询将提高SQL删除速度。 使用批量删除:Oracle PL / SQL具有批量删除操作符,通常比标准SQL删除更快。 丢弃指数&amp;约束:如果要在夜间批处理作业中调整删除,请考虑删除索引并在删除作业完成后重建它们。 Small pctused:对于调整批量删除,您可以通过将Oracle设置为仅在块为空时通过为pctused设置较低值来将块重新添加到空闲列表来减少空闲列表开销。 并行化删除作业:您可以与并行提示并行运行大量删除。如果您有36个处理器,则全扫描速度可以快35倍(cpu_count-1) 考虑NOARCHIVELOG:首先进行完全备份,然后将数据库退回到NOLOGGING模式以进行删除,然后在ARCHIVELOG模式后再次将其退回。 使用CTAS:您可以尝试的另一个选项是使用CTAS创建新表,其中select语句过滤掉要删除的行。然后重命名原始文件,然后重命名新表并传输约束和索引。 最后,抵制做“软”删除的诱惑,一种可能致命的脑死亡方法。
答案 2 :(得分:0)
这种方法有优势。 您可以在所需的表空间中创建一个表,而不会在磁盘所需的分区上出现碎片。 表的物理重新创建将删除表的碎片并删除链接的行。
如果您需要从表格中删除60-99%的行。 emp
然后你需要制作一个新表emp_new
。
create table emp_new ;
将所需行复制到新表
insert into emp_new select * from emp where date_insert> sysdate-30
在新表上创建索引
create index PK_EMP on emp_new.
删除旧的emp表
drop table emp.
将新表重命名为旧名称。
rename table emp_new to emp
答案 3 :(得分:-2)
在Oracle PL / SQL中,DDL语句应该在语句之前使用Execute Immediate。因此你应该使用:
autocmd InsertLeave <buffer> execute "normal! giXXX\<Esc>"
除了你还可以使用
execute immediate 'truncate table schema.tablename';
尝试在您的案例中可能有效的任何人