2

我有以下 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 张桌子。

4

3 回答 3

4

“它有效,但它需要永远!”

在这种情况下,永远意味着一张桌子不到三秒 :)

删除表格不仅仅是删除表格。还有一些依赖对象要删除 - 约束、索引、触发器、lob 或嵌套表存储等。有视图、同义词存储过程要失效。有要撤销的补助金。必须释放表的空间(及其索引等的空间)。

所有这些活动都会生成递归 SQL、从数据字典中选择或更新数据字典的查询,这些查询可能会执行得很差。即使我们不使用触发器、视图、存储过程,数据库仍然必须运行查询来确定它们不存在。

与普通 SQL 不同,我们无法调整递归 SQL,但我们可以调整环境以使其运行得更快。

我假设这是一个开发数据库,​​其中定期构建和拆除对象,并且您使用的是 10g 或更高版本。

  1. 清理回收站。

    SQL> purge recyclebin;

  2. 收集数据字典的统计信息(需要 DBA 权限)。这些可能已经被收集,因为这是 10g 和 11g 中的默认行为。 了解更多

  3. 获得字典统计信息后,请确保您使用的是基于成本的优化器。理想情况下,这应该在数据库级别设置,但我们可以在会话级别修复它:

    SQL> alter session set optimizer_mode=choose;

于 2010-10-07T04:45:53.050 回答
1

我会尝试更改 DROP TABLE 语句以使用Purge关键字。由于您要删除所有表,因此您实际上不需要同时级联约束。这个动作可能是导致它变慢的原因。我没有 Oracle 的实例来测试它,所以它可能会抛出一个错误。

如果它确实抛出错误,或者没有更快,我会删除 Sequence drop 命令以找出哪个命令花费了这么多时间。

Oracle 关于 DROP TABLE 命令的文档在这里

于 2010-10-07T01:34:42.313 回答
0

一种替代方法是删除用户而不是单个表等,并在需要时重新创建它们。它通常更健壮,因为它会删除所有表、视图、过程、序列等,并且可能会更快。

于 2013-12-13T13:02:05.857 回答