2010-04-14 128 views
10

將大量數據從CSV(300萬行+)加載到數據庫的最有效方法是什麼?C#將大量數據從CSV導入到數據庫

  • 的數據需要被格式化(例如名稱列需要被分成第一名和姓等)
  • 我需要做這在高效地即時間限制

我正在閱讀,使用C#應用程序逐行讀取,轉換和加載數據?這是理想的,如果不是,我的選擇是什麼?我應該使用多線程嗎?

+0

時間限制有多嚴格? – Jake 2010-04-14 22:54:11

回答

4

您將被I/O綁定,因此多線程不一定會使其運行速度更快。

上次我做到了這一點,它大概有十幾行C#。在一個線程中,它以儘可能快的速度運行硬盤,因爲它可以從盤片中讀取數據。我一次從源文件中讀取一行。

如果你不喜歡自己寫,你可以試試FileHelpers庫。您可能還想看看Sébastien Lorion's work。他的CSV閱讀器專門用於處理性能問題。

+0

是的,c#io庫的緩衝區很好。最近我不得不在一分鐘內從一個csv轉換到另一個(1.5米線)。 – 2010-04-14 22:46:03

+1

我也推薦FileHelpers。它使我不必編寫解析器來處理其中包含逗號的值。如果CSV有任何這樣令人討厭的細節,請考慮FileHelpers。 – 2010-04-14 22:49:18

+0

我知道在過去,驅動器上的尋找時間是一個問題。在大圖像文件的情況下,我們將從一個驅動器讀取數據並寫入另一個驅動器,以減少重新定位驅動器磁頭的次數。 – yamspog 2010-04-14 23:03:02

2

我同意你的解決方案。一次讀取一行文件應避免一次將整個文件讀入內存的開銷,這應該使應用程序快速高效地運行,主要是花時間從文件中讀取(這相對較快)並解析行。我注意的一點是要注意你的CSV中是否嵌入了換行符。我不知道您使用的具體CSV格式是否可能實際上在數據中的引號之間輸出換行符,但當然可能會混淆該算法。我想建議在將它們發送到數據庫之前將插入語句(在一個字符串中包括許多插入語句)批量化,如果這在檢索您需要用於後續外鍵的生成的鍵值時不存在問題(希望你不需要檢索任何生成的鍵值)。請記住,SQL Server(如果這就是你所使用的)每批只能處理2200個參數,所以限制你的批量大小來解決這個問題。我建議使用參數化的TSQL語句來執行插入操作。我懷疑插入記錄需要花費更多的時間,而不是從文件中讀取它們。

1

你沒有說明你正在使用哪個數據庫,但考慮到你提到的語言是C#我將假設SQL Server。

如果無法使用BCP導入數據(如果需要大量處理,聽起來好像不行),那麼SSIS很可能是下一個最快的選項。它不是世界上最好的開發平臺,但速度非常快。肯定比任何可以在任何合理時間內自行編寫的應用程序都快。

+0

我與Greg和JayRiggs合作。跳過C#(除非您正在爲SQL Server編寫CLR模塊)。讓SQL完成這項工作。如果您沒有聽說過,那麼從文件中處理大量數據是非常好的。 ;)這會爲您節省打開conxns等各種令人頭疼的問題。 – jcolebrand 2010-04-14 22:52:38

+0

這使得單元測試非常困難? – guazz 2010-04-14 23:26:13

+0

這實際上並不是單元測試非常有用的問題。人們過多地關注單元測試,忽視更大的圖景。你應該測試的是,如果已知CSV數據集,那麼進入數據庫的數據是正確的,並且按預期處理已知壞的情況(固定的,丟棄的或失敗的)。如果你這樣做,那麼它如何進入數據庫並不重要。所以從任何實際角度來看,我都會說SSIS和其他任何東西一樣可測試。 – 2010-04-15 11:26:20

3

您可以使用csvreader來快速讀取CSV。

假設您正在使用SQL Server,您可以使用csvreader的CachedCsvReader將數據讀取到DataTable中,您可以使用該數據表將SqlBulkCopy加載到SQL Server中。

+0

這就是我使用的。我喜歡csvreader,它是訪問分隔文件的一種非常方便的方式。 – galford13x 2010-04-14 23:12:25

+0

+1爲SqlBulkCopy – Kiril 2010-04-14 23:41:35

0

BCP非常快,所以我會用它來加載數據。對於字符串操作,一旦數據在那裏,我會在SQL上使用CLR函數。除了增加複雜性並損害性能之外,多線程無助於這種情況。

0

如果你真的想在C#中做到這一點,創建&填充一個DataTable,截斷目標數據庫表,然後使用System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable dt)。

+0

不幸的是,我需要更新現有的記錄,數據將每天加載。 – guazz 2010-04-14 23:27:17