我已經實現了一個應用程序,它從csv文件中獲取數據並插入到Sql DB中,我使用Linq到sql。我也有要求skipping那些有一些驗證的記錄, 達到此目的我使用了一個循環,並在循環內調用submitchnages()。批量從csv插入到數據庫使用Linq到sql
問題:此應用程序的記錄數量較少(< 100),但實際上不適合獲取更多3 - 4個記錄的csv文件。我只是簡單地運行我的應用程序對這些大文件,結果應用程序需要很長時間(5 - 6小時)。
請提出任何更好的方法。
我已經實現了一個應用程序,它從csv文件中獲取數據並插入到Sql DB中,我使用Linq到sql。我也有要求skipping那些有一些驗證的記錄, 達到此目的我使用了一個循環,並在循環內調用submitchnages()。批量從csv插入到數據庫使用Linq到sql
問題:此應用程序的記錄數量較少(< 100),但實際上不適合獲取更多3 - 4個記錄的csv文件。我只是簡單地運行我的應用程序對這些大文件,結果應用程序需要很長時間(5 - 6小時)。
請提出任何更好的方法。
Linq-to-SQL非常適合獲取數據庫的數據,或者一次性驗證和少量插入/更新。但是對於你正在做的事情(ETL),聽起來像你需要查看SqlBulkCopy
對象。繼續使用你的L2S對象來進行驗證,但是不要提交更改,只需將對象映射到一個好的舊式ADO.NET DataTable中,並且每隔1000條記錄就可以批量插入它們。
提及'SqlBulkCopy'。 – Steven 2011-05-07 15:02:53
如果性能是一個大問題,LINQ to SQL可能不是這項工作的工具。然而,折騰的LINQ to SQL出你的解決方案的大門之前,你可能會考慮以下幾點:
DataContext
。 DataContext
緩存所有發送到數據庫並從數據庫中檢索的實體,這將導致大量內存佔用並最終...內存不足。批量插入是O/RM不擅長的事情,所以您可能需要採取不同的方法。
如果您必須使用Linq2Sql進行插入操作,則可能需要進行間歇性提交。像這樣 -
public void LoadLargeDataUsingLinqToSql(string pathToCSV){
DataTable dt = LoadMyCSVToDataTable(pathToCSV);
int myPerformanceCounter = 0;
foreach(DataRow dr in dt.Rows()){
MyLinqClass m = ConvertDRToMyLinqClass(dr);
if(m.IsValidAndReadyToBeSaved()){
MyDataContext.MyLinqClassRef.InsertOnSubmit(m);
myPerformanceCounter++;
}
if(myPerformaceCounter>25000){
//Commit to clear cache.
MyDataContext.SubmitChanges();
myPerformanceCounter=0;
}
}
//Commit leftovers
MyDataContext.SubmitChanges();
}
'SubmitChanges'不清除'DataContext'的內部緩存。它將堅持所有的對象,甚至提交一次。你應該在調用'SubmitChanges()'後創建一個新的'DataContext'。 – Steven 2011-05-07 15:02:00
按緩存我並不是指DataContext緩存。我的意思是等待提交給數據庫的對象的邏輯緩存。創建新的數據環境並不總是可行的,除非你有一個非常嚴格的「工作單元」實現。 SQLBulk副本是典型數據加載程序的首選方法,但如果您想堅持純粹的基於對象的模型,那麼這種方法可以正常工作。在一分鐘內插入幾十萬個物體。 – YetAnotherUser 2011-05-07 17:40:23
請參閱http://blogs.msdn.com/b/dinesh.kulkarni/archive/2008/07/01/linq-to-sql-tips-9-understanding-datacontext-s-internal-caching.aspx。 L2S緩存不是一個非常昂貴的緩存。 – YetAnotherUser 2011-05-07 17:43:47
發佈相關的代碼? – 2011-05-06 22:34:31