目前我正在使用声明:
delete
from tbl_name
where trunc(tbl_name.Timestamp) = to_date('06.09.2013','DD/MM/YYYY');
但这需要很长时间。 有没有办法加快速度?
谢谢
答案 0 :(得分:3)
首先,这肯定是一张大桌子。否则,我认为像你这样的陈述没有意义。
然后有两种可能性:
1)删除语句影响许多记录。
然后说这句话很自然。必须扫描整个表格(全表扫描)。你只能通过并行化语句来加快速度:
delete /*+parallel(tbl_name,4)*/ from tbl_name ...
2)delete语句影响表中相当小比例的记录。
然后,Oracle建议使用索引。由于您只询问时间戳列的日期部分,因此您将创建一个函数索引:
create index index_name on tbl_name( trunc(the_timestamp) );
一旦表上有可用的索引,Oracle就可以使用它根据trunc(the_timestamp)查找有关选择,更新和删除的所需记录。
答案 1 :(得分:1)
在右侧使用介于值之间而不是在左侧使用trunc。
delete from tbl_name
where tbl_name.Timestamp between to_date('06.09.2013 00:00:00','DD/MM/YYYY hh24:mi:ss')
and to_date('06.09.2013 23:59:59','DD/MM/YYYY hh24:mi:ss');
答案 2 :(得分:0)
您可以使用更好的条件而不是trunc
,尤其是如果您在tbl_name.Timestamp字段上有索引:
tbl_name.Timestamp >= to_date('06.09.2013','DD/MM/YYYY') --inclusive
AND tbl_name.Timestamp < to_date('07.09.2013','DD/MM/YYYY') --exclusive
我假设你没有trunc(tbl_name.Timestamp)上的函数索引,在这种情况下应该提供更好的性能。
<子> 根据我以前的经验,(没有直接的事实或理论支持,甚至更多,the facts are against this approach):你可以把它分成更小的一串
delete
from tbl_name
where
id in (select id from tbl_name
and trunc(tbl_name.Timestamp) = to_date('06.09.2013','DD/MM/YYYY')
and rownum<10000); -- tune this to your liking
重复一遍。不要忘记介于两者之间......这对我有帮助,我们使用的是SNAPSHOT隔离级别。
答案 3 :(得分:0)
我在想,既然您指的是tbl_name.Timestamp
列,那么我确信必须有一个与之关联的主键。如果主键是数字值,您可以在delete语句中使用该索引,类似于:
从 LOWER_ID_VALUE 与 UPPER_ID_VALUE
之间的 tbl_name.ID 中的tbl_name删除
注意:LOWER_ID_VALUE和UPPER_ID_VALUE本质上是包含性的,这意味着这两个ID的记录也将被删除。
ppeterka 66使用rownum分解删除的想法是不可行的。看看http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2345591157689假设您正在运行Oracle,当发出DELETE命令时,已删除的行将存储在回滚段中,因此,如果需要,可以撤消更改。因此,回滚中的行的图像当前不存在于表中。现在所有的回滚块也被写入重做日志文件。所以你有表的数据块(当然没有删除的行)和旧图像的回滚块都产生重做,这会占用额外的存档日志。
因此,最好一步到位,而不是将其分解为多个交易并进行。