我有一个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
但我也没有找到任何阻止。
如何删除这些大数据而没有任何问题?
答案 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
上创建索引时您可能会值得,然后您将删除。这可能意味着您的整个操作需要更长时间,但至关重要的是,它会减少您删除行所需的时间。
另一方面,如果您要删除大量行,您可能会发现
更好rename
命令交换表格。要记住的另一件事是,删除比其他交易吃掉更多的UNDO,因为它们需要更多的信息来回滚。因此,如果您的记录很长和/或很多,那么您的DBA可能需要检查UNDO表空间(如果您仍在使用它们,则需要回滚segs)。
最后,你做过任何调查,看看时间到底在哪里? DELETE语句只是另一个查询,可以使用普通的调整技巧来解决它们。