2012-04-11 90 views
4

我有一个包含大约100k条记录的表,并且我想要删除一些行,问题在于DELETE语句运行速度非常慢 - 它在30分钟内未完成。但select声明是在1秒内返回。删除语句在Oracle中非常缓慢

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   

如何杀死这些会话:表是由多届锁定?

在我锁定表的会话结束后,问题已解决,感谢所有的帮助。 -

+0

你是如何确定它没有完成的?也许它已经完成,但没有提交,并且您看不到从其他连接发生删除直到它被提交。 – 2012-04-11 07:25:14

+0

我在sqlplus控制台中运行它,它只是没有返回。所以我认为该声明仍在执行中。 – 2012-04-11 07:28:23

+0

杀害会话是一个完全不同的话题。请提出一个新问题(以便其他人可以更容易地找到该解决方案)。然后,从这个问题添加一个链接到新的链接。 – 2012-04-11 08:00:32

回答

7

可以有很多原因:

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

+0

如何检查行是否被任何人锁定? – 2012-04-11 07:35:15

+0

我添加了几个链接。 – 2012-04-11 07:38:55

+0

所以表被许多会话锁定。看到编辑的问题。如何杀死会话? – 2012-04-11 07:52:50

1

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

这听起来像额外的代码正在运行的删除,这表示可能会触发器也正在运行的表上。你能检查一下吗?

+0

表格中没有任何触发器,也没有任何REFERENCE CONSTRAINTS。 – 2012-04-11 07:30:47

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') 
); 

如果tabels中的字段相同的顺序定义,这可能工作太:

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; 
+0

谢谢休伯特。我想知道为什么DELETE语句如此缓慢,因为表中只有大约10万条记录。 – 2012-04-11 07:37:41

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%。)