2010-08-25 45 views
6

我終於得到我的插入批處理工作,現在我一直在擺弄批處理的大小,但我看不到50之間的值和10000的值之間的性能差異。這似乎很對我來說很奇怪,但我不知道幕後發生了什麼,所以這可能是正常的行爲。如何將DataAdapter.UpdateBatchSize設置爲「最佳」值?

我將160k行插入表中,測試值的平均值爲115 +/- 2秒。沒有配料需要210秒,所以我對這種改進非常滿意。目標表是:

CREATE TABLE [dbo].[p_DataIdeas](
    [wave] [int] NOT NULL, 
    [idnumber] [int] NOT NULL, 
    [ideaID] [int] NOT NULL, 
    [haveSeen] [bit] NOT NULL CONSTRAINT [DF_p_DataIdeas_haveSeen] DEFAULT ((0)), 
    CONSTRAINT [PK_p_DataIdeas] PRIMARY KEY CLUSTERED 
(
    [wave] ASC, 
    [idnumber] ASC, 
    [ideaID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON 
) ON [PRIMARY] 
) ON [PRIMARY] 

我讀What to look for when setting UpdateBatchSize,答案是簡單地測試了幾個不同的值。我可以理解,但是如果知道表格設計,SQL問題和即將插入的數據,那麼不應該有可能計算或至少猜測一個好的價值嗎?

有人可以推薦的最佳做法嗎?

回答

5

您可以通過查看SQL事件探查器或致電SqlConnection.RetrieveStatistics()來查看批處理的效果。你應該看到每個批次對應於一次往返數據庫。

就如何優化批量大小而言,一個非常粗略的規則是,當批量大於50時,性能往往會停止改進 - 實際上,有時大批量的批量運行速度可能會比小批量的慢。如果我太忙而無法測試,通常我會從一批大約20開始(除非我使用表值參數,批量高達500可比小型參數快)。但是,最佳數量取決於插入的總大小(它們是否都適合RAM),數據庫日誌所在的磁盤有多快,日誌是否位於其自己的驅動器/ LUN上(如果不是,則爲大的性能成本)等等。

可達到的速度通常首先受到往返次數的限制,然後是事務大小,然後記錄磁盤速度(特別是順序訪問是可能的還是強制隨機由於與同一主軸上的其他文件競爭),最後是RAM。但是,所有這些因素在一定程度上也是相互關聯的。

改善插入性能的第一步是在交易中完成它們 - 也許每一批或兩批交易一次。除此之外,表值參數可能是下一步,使用存儲過程INSERT INTO Table SELECT column FROM @TableArgument

1

儘管更改UpdateBatchSize會有所幫助,但使用DataAdapter更新大量記錄的基本方法將會很慢。這是因爲最終,DataAdapter會爲每一行生成一個單獨的SQL語句(插入,更新或刪除)。 UpdateBatchSize僅影響發送到SQL Server時在一個TSQL批處理中發送的單個語句的數量。

爲了獲得更大的性能改進,您希望SQLServer在一個語句中插入/更新/刪除多個記錄(通常使用某種JOIN)。表值參數(如RickNZ所述)是這樣做的一種方式。另一種可能是使用SqlBulkCopy(儘管你通常需要使用一個臨時表)。

0

確保還有一個活動事務,它會極大地提高性能(在使用MysqlDataAdapter進行的測試中大約爲30倍)。

相關問題