2012-04-11 53 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%。)