如何从Oracle 9i DB中删除大数据?

时间:2010-02-02 07:36:57

标签: oracle oracle9i

我有一个5 GB的表,现在我试图删除如下:

delete  from tablename
where to_char(screatetime,'yyyy-mm-dd') <'2009-06-01' 

但它运行时间很长,没有回应。与此同时,我试图检查是否有人阻止了以下内容:

select l1.sid, ' IS BLOCKING ', l2.sid
from v$lock l1, v$lock l2
where l1.block =1 and l2.request > 0
and l1.id1=l2.id1
and l1.id2=l2.id2

但我也没有找到任何阻止。

如何删除这些大数据而没有任何问题?

4 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

如果screatetime上有索引,您的查询可能没有使用它。更改语句,以便where子句可以使用索引。

delete from tablename where screatetime < to_date('2009-06-01','yyyy-mm-dd')

答案 2 :(得分:1)

首先锁定表格时,它运行得更快。还要按照Rene的建议更改where子句。

LOCK TABLE tablename IN EXCLUSIVE MODE;

DELETE FROM tablename
where screatetime < to_date('2009-06-01','yyyy-mm-dd');

编辑:如果表格无法锁定,因为它经常被访问,您可以选择萨拉米战术删除这些行:

BEGIN
  LOOP
    DELETE FROM tablename
      WHERE screatetime < to_date('2009-06-01','yyyy-mm-dd')
        AND ROWNUM<=10000;
    EXIT WHEN SQL%ROWCOUNT=0;
    COMMIT;
  END LOOP;
END;

总的来说,这会慢一点,但它不会破坏你的回滚段,你可以在另一个会话中看到进度(即tablename中的行数下降)。如果你因为某些原因必须杀掉它,那么回滚将不会永远消失,你到目前为止还没有完成所有的工作。

答案 3 :(得分:1)

5GB不是表大小的有用度量。行总数很重要。您要删除的行数占总事项的比例。行的平均长度很重要。

如果要删除的行的比例很小,那么在screatetime上创建索引时您可能会值得,然后您将删除。这可能意味着您的整个操作需要更长时间,但至关重要的是,它会减少您删除行所需的时间。

另一方面,如果您要删除大量行,您可能会发现

更好
  1. 使用创建表的副本   '从t1创建表t1_copy作为select *        screatedate&gt; = to_date('2009-06-01','yyyy-mm-dd')`
  2. 使用rename命令交换表格。
  3. 重新应用约束,索引到新的T1。
  4. 要记住的另一件事是,删除比其他交易吃掉更多的UNDO,因为它们需要更多的信息来回滚。因此,如果您的记录很长和/或很多,那么您的DBA可能需要检查UNDO表空间(如果您仍在使用它们,则需要回滚segs)。

    最后,你做过任何调查,看看时间到底在哪里? DELETE语句只是另一个查询,可以使用普通的调整技巧来解决它们。