2016-03-02 9 views
5

我有一個場景,我必須定期刪除數十萬行(基於服務器決策或某個固定的時間間隔)。我正在使用entityframework 6.0並且問題是正常的Remove()方法對於批量操作來說很慢。我正在考慮一些可能的情況:選擇優化的方式來刪除oracle中的行,雖然實體框架

案例1:通過實體框架,使用RemoveRange。

var db = new MyDbContext(); 
var itemsToDelete = db.TableFoo.Where(x=>!x.new); 
db.MyTable.RemoveRange(itemsToDelete); 
db.SaveChanges(); 

我檢查了這一點,這比在foreach中單獨使用Remove更快。但它仍然發送oracle原子sql而不是批處理。

案例2:通過實體框架調用一些程序或者包,它們將對錶執行刪除操作。雖然它在我看來是最快的選擇,但我仍然必須在這裏弄清楚什麼是最好的SQL刪除方法,我知道截斷,但它不會在這裏達到目的。我所知道的是:

CREATE OR REPLACE PROCEDURE deleteDBFoo(p_toc IN DBFOO.TOC%TYPE) 
IS 
BEGIN 

    DELETE DBFOO where TOC < "SOME DATE"; 

    COMMIT; 

END; 

案例3:要自動在Oracle這個任務(不知道這是可能的或好主意)的情況下的標準是由一些固定日期刪除所有舊行-時間間隔。

什麼是處理這種情況的優化方法?除了這些情況之外,如果還有其他更好的方法,請對此有所瞭解。

UPDATE1:做一些分析後,我發現了以下結果:

對於數據庫中

刪除一個百萬行TRUNC表了3.46秒。案例2:耗時37.398秒 案例1:耗時數分鐘。 對於我的解決方案,我將與案例2一起去,但我仍然比案例2更好地等待解決方案或以某種方式改進它。

回答

0

刪除批量數據的最快方法是在服務器端執行此操作。

在你的情況下,因爲你想要使用實體框架,你應該創建一個帶有參數的存儲過程,並且從存儲過程execute中獲取代碼。

如果您想使用案例1,則實體框架很慢;因爲每次刪除都會創建一個查詢並執行它。


嘗試這樣:

CREATE OR REPLACE PROCEDURE DeleteUnnecessaryData 
(endDate IN DATE) 
IS 
BEGIN 

    DELETE DBFOO where TOC < endDate; 

    COMMIT; 

END; 
+0

如何 「在服務器端做」?你的意思是使用一些觸發器? 第二點你的解決方案看起來像情況2,你對我寫過的存儲過程滿意嗎,或者有更好的方法來完成它。 第三點雅我同意你關於案例1 :) – MKMohanty

+0

當你創建一個存儲過程時,你只發送執行查詢的命令給服務器;從存儲過程中刪除在服務器上執行的服務器。 –

+0

你寫了類似db.Database.SqlQuery(「exec DeleteUnnecessaryInfo @startdate」,startdateParam) –