10

我有一个包含大约 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

4 回答 4

9

可能有很多原因:

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

于 2012-04-11T07:26:08.577 回答
6

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

也许这有帮助:

在没有任何引用、触发器和其他索引的情况下复制该表。然后这样做:

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;
于 2012-04-11T07:31:10.100 回答
1

显然,删除操作将比选择花费更长的时间,但这并不能说明您看到的差异。

听起来在删除时正在运行其他代码,这表明表上可能有触发器也在运行。你能检查一下吗?

于 2012-04-11T07:20:21.487 回答
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。)

于 2012-04-11T07:44:18.770 回答