Oracle中的删除语句非常慢

Elv*_*Lou 7 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;
Run Code Online (Sandbox Code Playgroud)

DELETE声明如下:

delete from daily_au_by_service_summary 
    where summary_ts > to_date('09-04-2012','dd-mm-yyyy');
Run Code Online (Sandbox Code Playgroud)

此表的唯一索引位于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         
Run Code Online (Sandbox Code Playgroud)

如何杀死这些会话?

在我杀死锁定表的会话之后问题已经解决了,感谢大家的帮助. -

Aar*_*lla 8

可能有很多原因:

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


Hub*_*ast 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') 
);
Run Code Online (Sandbox Code Playgroud)

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

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

在那之后:

truncate daily_au_by_service_summary
Run Code Online (Sandbox Code Playgroud)

进而:

insert into daily_au_by_service_summary (field1, field2, ...) values (
    select field1, field2, ...
    from new_table; 
);
Run Code Online (Sandbox Code Playgroud)

不再需要新表:

drop new_table;
Run Code Online (Sandbox Code Playgroud)