删除SQL - 永远

时间:2016-06-10 19:04:09

标签: sql oracle12c dml

删除SQL脚本需要很长时间,甚至永远挂在Oracle 12c中。我们有数百个删除脚本,如下所示,甚至尝试通过并行操作/ * + PARALLEL(a,4)* /运行它,但在性能改进方面没有运气。

  1. 有没有办法调整删除脚本。
  2. 我们可以使用PL / SQL - for循环来提高性能吗?
  3. 如果是,请分享您的想法和意见。
  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;
    

2 个答案:

答案 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 oldtableINSERT /*+ APPEND */ INTO oldtable SELECT * from newtable;来写回正确的数据。

这实际上取决于你所处的情况(正如其他人评论的那样 - 你在表中有多少行,你想要删除多少行等等。)

hth: - )

答案 1 :(得分:0)

根据它是否是一次性交易,创建一个只包含您想要保留的行的新表通常要快得多:

Gtk::Layout

然后删除旧表并重命名新表。

如果你有一些,你可能需要重新创建索引/ fk。