删除SQL脚本需要很长时间,甚至永远挂在Oracle 12c中。我们有数百个删除脚本,如下所示,甚至尝试通过并行操作/ * + PARALLEL(a,4)* /运行它,但在性能改进方面没有运气。
一些示例SQL脚本:
DELETE
FROM
E_PROJ_DETAIL
WHERE
CATEGORY_ID in (SELECT PRIMARY_KEY FROM Y_OBJ_CATEGORY WHERE TREE_POSITION='VEN$_MADD');
COMMIT;
delete
from
e_proj_group_access
where enterprise_object_id in (select primary_key from t_project where application_id in (select application_id from y_object_definition where unique_code ='VEN$_MADD'));
commit;
答案 0 :(得分:0)
我不知道是否有可能调整'删除语句,可能除了先提前删除任何无用(=未使用)的索引和约束,然后再重新创建它们。
在这些情况下(删除很多行)我使用FOR
循环内部提交,如下所示:
I := 0;
FOR c IN (SELECT id FROM table WHERE [conditions to delete])
LOOP
DELETE FROM table WHERE t.id = c.id; /* id = primary key */
IF (I > 1000) THEN
COMMIT;
I := 0;
END IF;
I := I + 1;
END LOOP;
但是在这里你偶尔可以遇到ORA-01555: snapshot too old
,因为你将删除你在FOR
循环中打开游标的同一个表中的行。
在其他情况下,您可以CREATE TABLE newtable AS SELECT * FROM oldtable WHERE [conditions for rows I want to keep]
然后执行TRUNCATE oldtable
和INSERT /*+ APPEND */ INTO oldtable SELECT * from newtable;
来写回正确的数据。
这实际上取决于你所处的情况(正如其他人评论的那样 - 你在表中有多少行,你想要删除多少行等等。)
hth: - )
答案 1 :(得分:0)
根据它是否是一次性交易,创建一个只包含您想要保留的行的新表通常要快得多:
Gtk::Layout
然后删除旧表并重命名新表。
如果你有一些,你可能需要重新创建索引/ fk。