2012-02-16 66 views
1

解析某些數據並將其從.NET中插入到3個表中。使用表值參數來傳遞數據,因爲一些插入是600,000行。傳遞對象(不是數據表),它們通過引用(TVP的性質)傳遞。由於插入值一次限制爲1000行,所以獲得了100:1的增益超過直插值。在存儲過程中,從TVP向實際表的插入按聚簇索引排序。這些表除聚簇索引外沒有索引。 SP使用TABLOCK,因爲這些是一次寫入表和一個數據加載器。填充因子100.數據或事務日誌大小沒有增加 - 其大小適合總數據負載。最後回答這個問題。在過去的4個小時內插入了2億行。插入響應時間減少了1/2。如果填充因子是100,我插入按聚簇索引排序,那麼爲什麼響應下降?我能做些什麼來解決這個問題?表格插入率減慢AsTable大小增加

我沒有得到TVP,直到我用它 - 它就像一個反向的DataReader。

我想感謝您的幫助,並對不正確的問題陳述表示歉意。對於每個解析(在這種情況下,我解析200,000)插入按聚簇索引排序。但是,3個表中只有1個是聚簇索引順序中的下一個解析。解析70,000後,良好的表的掃描密度爲99%,但其他兩個表的嚴重碎片化,掃描密度爲12%。

在兩個分段表上設置填充因子50並重新編制索引。現在我獲得了最大速度的1/3。我只需要停止該過程並每隔幾個小時重新索引。

我最終做的是更改聚集索引以匹配插入順序。創建了一個獨特的索引,以前曾是聚類。我禁用唯一索引插入數據,然後重建唯一索引。在這種情況下,我可以在10小時內獲得300:1的表現。這不是一個額外的0 - 三百比一。這不是欺騙 - 與起始索引和填充因子或30相比,即使有額外的索引,我的表格尺寸也更小,因爲我可以將兩個填充因子都設置爲100.

我使用#temp on some查詢,以便我可以按照查詢已知的順序獲取行。我將#temp轉換爲TVP並增加了1/2秒(大約需要創建和刪除#temp的時間)。

+0

我假設目標表上沒有約束,觸發器或非聚簇索引?對不起,我沒有用TVPs做過很多性能分析,所以我不確定還有什麼可能會干擾。哦,我編輯了標籤,它已經存在。 :-) – 2012-02-16 02:31:00

+0

@AaronBertrand謝謝,我沒有找到標籤。整個數據庫中沒有觸發器。有兩個約束,但不改變約束邊表。如果我的代碼沒有被破壞,那麼應該沒有違反約束。你認爲我應該禁用對插入的約束檢查?如果禁用約束檢查並違反約束會發生什麼情況。在這種情況下,TVP就像是大容量拷貝,但是來自內存對象。直接從一些用於在解析中查找唯一值和唯一值對的字典提供TVP。 – Paparazzi 2012-02-16 02:52:40

+0

錯誤三個表中的一個上有非聚集索引。該表是三個中最小的一個,因數爲100,非聚集索引位於單個列上。該表上的索引是160 KB,大約是其他兩個索引合併的兩倍。單憑這一點就能降低速度嗎?我想我可以對索引進行填充並測試? – Paparazzi 2012-02-16 03:06:45

回答

0

每個操作轉換評論回答...

除了自動統計爲@SqlACID提到,約束檢查可以得到更貴的表填滿。如果我要認真加載表格,我通常打算禁用或刪除索引和約束,並在之後重新創建它們,如果速度是我的最終目標的話。這可能意味着在違反約束條件之後刪除行,或者在可能的情況下對批量數據進行更好的驗證。