2010-07-22 135 views
0

公司每天都會將包含潛在許多記錄(350,000)的文本文件放到我們的安全FTP上。我們已經創建了一個在早期運行的Windows服務,以便將文本文件讀入我們的SQL Server 2005數據庫表中。我們不做BULK插入,因爲數據是關係數據,我們需要根據數據庫中已有的數據進行檢查,以確保數據保持正常和一致。大數據服務體系結構

問題在於服務可能需要很長時間(小時)。這是有問題的,因爲它插入和更新到表中,這些表經常需要由我們的應用程序查詢和掃描,這可能會影響數據庫和應用程序的性能。

我們想到的一個解決方案是使用與我們的實時數據庫相同的表在單獨的數據庫上運行服務。服務完成後,我們可以在活動數據庫中執行BCP,以反映由服務創建的所有新記錄。

我從來沒有在數據庫中處理過數百萬條記錄,我不確定這樣的標準方法是什麼。這是做這種事情的適當方式嗎?有什麼建議麼?

回答

2

我見過的一種機制是將值插入臨時表 - 與目標表具有相同的模式。空ID表示新記錄,填充ID表示更新的記錄。然後使用SQL合併命令將其合併到主表中。合併將比個別插入/更新執行得更好。

單獨執行此操作會導致對錶格上的索引進行維護 - 如果它對選擇進行了調整,則花費可能會很高。我相信合併它的一項大規模行動。

它在這裏感動: What's a good alternative to firing a stored procedure 368 times to update the database?

大約有SQL合併MSDN文章,所以谷歌搜索將幫助你。

更新:事實證明,你不能合併(你可以在2008年)。你有另一個數據庫的想法通常由SQL複製來處理。我再次在生產中看到用於執行長時間運行的操作(在此實例中報告和聚合數據)的當前數據庫的副本,但是沒有合併回去。我不知道可用的合併功能在SQL複製 - 但它是一個很好的地方看。

要麼,要麼解決你無法批量插入/更新的原因。

更新2:正如在註釋中提到的那樣,您可以堅持使用臨時表的想法將數據導入數據庫,然後在該表中插入/更新連接以填充主表。現在不同的是,SQL正在使用一個集合,因此可以相應地調整任何索引重建 - 即使加入也應該更快。

更新3:您可能會從插入過程中刪除數據檢查並將其移至服務。如果您可以在發生這種情況時停止插入表格,那麼這將允許您解決阻止您進行批量插入的問題(即,您正在根據列值檢查重複項,因爲您還沒有奢侈品ID)。或者用臨時表的想法,你可以添加一個WHERE先看看情況,如果在數據庫中存在該行,是這樣的:

INSERT INTO MyTable (val1, val2, val3) 
SELECT val1, val2, val3 FROM #Tempo 
WHERE NOT EXISTS 
( 
    SELECT * 
    FROM MyTable t 
    WHERE t.val1 = val1 AND t.val2 = val2 AND t.val3 = val3 
) 
+0

+1 350.000行的批量插入應該在不到一分鐘內完成。 'merge'在2005年不可用,但是從這個問題來看,插入RealTable(col1,col2)從TempTable中選擇col1,col2在這裏可以工作 – Andomar 2010-07-22 15:12:21

+0

啊我沒有注意到標籤 - 我會修改我的答案。不幸的是,OP還表示他不能批量插入。 – 2010-07-22 15:13:14

0

在開始複製和複製數據(這是複雜且昂貴的)之前,檢查現有服務以確保其有效運行是值得的。

也許有表格掃描,你可以通過添加一個索引或刪除查找查詢,你可以通過做聰明的錯誤處理擺脫?分析您的服務執行並優化這些查詢的執行計劃。

2

我們做更大的進口比所有的時間。創建一個SSIS pacakge來完成這項工作。我個人更喜歡創建一個臨時表,清理它,然後進行更新或導入。但是如果你想在插入之前進行清理,SSIS可以完成所有的清理工作。