Oracle中的删除语句非常慢

时间:2012-04-11 07:13:06

标签: sql oracle

我有一个包含大约100k记录的表,我想删除一些行,问题是DELETE语句运行得非常慢 - 它在30分钟内没有完成。但是select语句在1秒后返回。

SELECT语句如下:

select * from daily_au_by_service_summary 
    where summary_ts >= to_date('09-04-2012','dd-mm-yyyy') 
    order by summary_ts desc;

DELETE语句如下:

delete from daily_au_by_service_summary 
    where summary_ts > to_date('09-04-2012','dd-mm-yyyy');

此表格中唯一的索引位于summary_ts

可能是什么原因?

编辑:桌子被许多会话锁定:

SESSION_ID ORACLE_USERNAME                OS_USER_NAME                   OBJECT OWNER                   OBJECT_NAME                                                                                                                      OBJECT_TYPE         LOCKED_MODE
---------- ------------------------------ ------------------------------ ------------------------------ -------------------------------------------------------------------------------------------------------------------------------- ------------------- -----------
       213 T03RPT                         elou                           T03RPT                         DAILY_AU_BY_SERVICE_SUMMARY                                                                                                      TABLE                         3 
       203 T03RPT                         elou                           T03RPT                         DAILY_AU_BY_SERVICE_SUMMARY                                                                                                      TABLE                         3 
       202 T03RPT                         elou                           T03RPT                         DAILY_AU_BY_SERVICE_SUMMARY                                                                                                      TABLE                         3 
       190 T03RPT                         elou                           T03RPT                         DAILY_AU_BY_SERVICE_SUMMARY                                                                                                      TABLE                         3 
       189 T03RPT                         elou                           T03RPT                         DAILY_AU_BY_SERVICE_SUMMARY                                                                                                      TABLE                         3 
       188 T03RPT                         elou                           T03RPT                         DAILY_AU_BY_SERVICE_SUMMARY                                                                                                      TABLE                         3 
       187 T03RPT                         elou                           T03RPT                         DAILY_AU_BY_SERVICE_SUMMARY         

如何杀死这些会话?

在我杀死锁定表的会话后,问题已得到解决,感谢大家的帮助。 -

4 个答案:

答案 0 :(得分:7)

可能有很多原因:

如果外键是问题,通常的解决方案是在外部列上添加索引:对于每次删除,Oracle需要检查这是否会违反外键关系。

答案 1 :(得分:3)

删除更改表格内容的方法。这意味着,在每个删除的行之后,必须更新所有索引并且必须检查所有外键引用。这可能需要很长时间!

也许这会有所帮助:

制作该表的副本,不包含任何引用,触发器和其他索引。然后这样做:

insert into new_table (field1, field2, ...) values (
    select field1, field2, ...
    from daily_au_by_service_summary 
    where summary_ts < to_date('09-04-2012','dd-mm-yyyy') 
);

如果表格中的字段按相同顺序定义,这也可能有效:

insert into new_table values (
    select *
    from daily_au_by_service_summary 
    where summary_ts < to_date('09-04-2012','dd-mm-yyyy') 
);

之后:

truncate daily_au_by_service_summary

然后:

insert into daily_au_by_service_summary (field1, field2, ...) values (
    select field1, field2, ...
    from new_table; 
);

不再需要新表:

drop new_table;

答案 2 :(得分:1)

显然,删除操作所需的时间比选择时间长,但这并不能解释您所看到的差异。

这听起来像是在删除时运行了额外的代码,这表示桌面上可能还有正在运行的触发器。你能看看吗?

答案 3 :(得分:0)

当DML操作需要很长时间时,使用剩余行创建新表并删除上一个表,而不是删除。

我的意思是,

create table NEW_TABLE as
select * from daily_au_by_service_summary  
where summary_ts <= to_date('09-04-2012','dd-mm-yyyy'); 

这会更快,尤其是在删除大量行时。 (例如,总行数的%10。)