我有以下Oracle SQL:
Begin
-- tables
for c in (select table_name from user_tables) loop
execute immediate ('drop table '||c.table_name||' cascade constraints');
end loop;
-- sequences
for c in (select sequence_name from user_sequences) loop
execute immediate ('drop sequence '||c.sequence_name);
end loop;
End;
它是由另一个开发者给我的,我不知道它是如何工作的,但它会丢弃我们数据库中的所有表。
它有效,但需要永远!
我不认为放弃我的所有表应该花那么长时间。这是怎么回事?并且,这个脚本可以改进吗?
注意:大约有100个桌子。
答案 0 :(得分:4)
“它有效,但需要永远!”
永远在这种情况下意味着不到三秒钟的表:)
除了丢弃表之外,还有更多的东西要删除表。还有依赖对象也可以删除 - 约束,索引,触发器,lob或嵌套表存储等。有视图,同义词存储过程无效。有补助金被撤销。表的空间(及其索引等)必须取消分配。
所有这些活动都会生成递归SQL,从数据字典中选择或更新数据字典的查询,以及哪些可以执行得非常糟糕。即使我们不使用触发器,视图,存储过程,数据库仍然必须运行查询以确定它们的缺失。
与普通SQL不同,我们无法调整递归SQL,但我们可以调整环境以使其更快地运行。
我认为这是一个开发数据库,其中对象会定期构建和拆除,并且您使用的是10g或更高版本。
清除回收站。
SQL> purge recyclebin;
收集数据字典的统计信息(需要DBA权限)。这些可能已经被收集,因为这是10g和11g中的默认行为。 Find out more。
一旦获得字典统计信息,请确保使用基于成本的优化程序。理想情况下,这应该在数据库级别设置,但我们可以在会话级别修复它:
SQL> alter session set optimizer_mode=choose;
答案 1 :(得分:1)
我会尝试更改DROP TABLE语句以使用Purge
关键字。由于丢弃所有表,因此实际上不需要同时级联约束。这个动作可能是导致它变慢的原因。我没有Oracle的实例来测试它,所以它可能会引发错误。
如果它确实抛出了错误,或者没有更快,我会删除Sequence drop命令以确定哪个命令占用了这么多时间。
Oracle关于DROP TABLE命令的文档是here。
答案 2 :(得分:0)
一种替代方法是删除用户而不是单个表等,并在需要时重新创建它们。它通常更加健壮,因为它会删除所有表,视图,过程,序列等,并且可能会更快。