2011-02-17 35 views
2

我想要儘可能高效地插入到數據庫中,並且有大量不斷傳入的數據(每分鐘大約10,000個,並且正在增長)。目前我正在使用準備好的插入語句,但我正在考慮使用SqlBulkCopy類以更大的塊導入數據。快速插入;使用關係數據的BulkCopy

問題是我沒有插入到單個表中 - 數據項的元素被插入到許多表中,並且他們的標識列被用作同時插入的其他行中的外鍵。我知道批量複製並不意味着允許更復雜的插入,但我想知道是否值得在uniqueidentifier列中交換我的身份列(在這種情況下是bigint)。這將允許我爲每個表執行幾個批量複製,並且由於我可以在插入之前確定ID,所以我不需要檢查SCOPE_IDENTITY之類的任何內容,這些內容阻止我使用批量複製。

這聽起來像是一個可行的解決方案,或者我可能會遇到其他潛在問題嗎?或者,還有另一種方法可以快速插入數據,但保留使用bigint標識列嗎?

謝謝。

回答

1

這聽起來像是你正計劃與「數據準備例程分配GUID代理鍵」方法交換「SQL分配一個[bigint身份()列]代用鍵」。換句話說,密鑰不會在SQL中分配,而是從外部SQL分配。鑑於你的數量,如果數據生成過程可以分配代理鍵,我肯定會去。

問題就變成了,你必須使用GUID,還是數據生成過程可以產生自動遞增整數?創建這樣一個始終如一地運行的進程是很困難的(爲什麼你爲SQL Server支付$ $$$的原因之一),但是在數據庫中更小和更人性化的密鑰的權衡可能是值得的。

+1

「創建這樣一個可以持續且可靠工作的過程很難...」沒錯,但是如果你在數據庫之外的一個單獨的非共享應用程序中執行它,它會容易得多。沒有爭用,沒有競爭條件,沒有交易。 –

+0

我嘗試了GUID,獲得了10倍的性能(approp。10,000 inserts per second)。 :) – Barguast

3

uniqueidentifier可能會讓事情變得更糟:頁面分割和更寬。見this

如果你的負載/可以批量,一個選項是:

  • 加載一個臨時表
  • 負載的實際表中一氣呵成作爲存儲過程
  • 使用每個批次的臨時表中的uniqueidentifier

我們處理每秒大約50k行的峯值(以這種方式增加)。實際上,我們使用單獨的臨時數據庫來避免雙重事務日誌寫入)

+0

我正在試驗一個在C#中生成的順序GUID(aka.COMB),我認爲應該從鏈接中解決聚集索引問題。乍一看,我非常喜歡你的臨時表想法,我假設這是爲了存儲具有GUID PKs的行,然後將它們轉移到具有IDENTITY PK的表中。但是,這是否仍然需要執行大量的INSERT,因爲我需要獲取標識列?也許我是誤解。 – Barguast

+1

@Bargauast:我們使用GUID來標識一個批處理(一些來自SQL BulkCopy,其他風險引擎也生成了一些)。然後我們用bigint聚集鍵將其刷入主表。GUID不是聚簇鍵,只是一種跟蹤批量數據以清除主表的方法。 GUID仍然是16個字節寬,無論順序與否,這加起來超過數十億行。 – gbn