2011-08-17 201 views
10

我在sql server上執行一些測試,我想獲得最佳插入速度。 我使用的語句是這樣的:Sql插入加速

INSERT INTO db_Test_databse..tbl_test with(rowlock) 
    ( joinid, date_key, 
     col1, col2,col3,col4, col5, col6, col7, col8, col9, col10, ...  
    ) 

SELECT tabid as joinid, 
     date_key, 
     rec_type, 
     col2, 
     dbo.udf_convert_hex_to_dec(col3), 
     col4, col5, col6, col7, col8, 
     dbo.udf_convert_hex_to_dec(col9), 
     dbo.udf_convert_hex_to_dec(col10), 
     ... 
from source_table f 

有25列;其中大部分是bigint或int類型的。

我刪除了目標表中的所有索引,除了主鍵是一個標識字段。

有關如何提高性能的更多提示?

P.s.在這種形式下,我的平均速度爲16.000行/秒。

+0

之前,你的店過程中使用'dbo.udf_convert_hex_to_dec'是殺你。你正在使用哪個版本的SQL Server?有內置的功能可以完成這種轉換。 – Yuck

+0

我在懷疑'udf_convert_hex_to_dec'函數。插入只能更快地達到某個點,一些因素是索引和物理IO性能。針對它運行一個查詢分析器,我敢打賭,select是由於函數的緩慢部分。 –

+2

用戶定義的函數可能很慢。你不能直接將十六進制轉換爲十進制 - CAST(col9 AS Decimal(4))例如>? – Simon

回答

14

爲了得到最好的性能,你應該:

  • 刪除表上的所有觸發器和約束
  • 刪除所有索引,除了那些由插入所需
  • 確保您的聚集索引是這樣的,新的記錄將永遠插入到表格的最後(一個標識列將會很好)。這可以防止頁面拆分(因爲現有頁面已滿,SQL Server必須移動數據)
  • fill factor設置爲0或100(它們是等效的),以便表格中沒有空格留空,從而減少頁面數量數據傳播。
  • 將數據庫的recovery model更改爲Simple,從而減少事務日誌的開銷。

多個客戶端是否並行插入記錄?如果是這樣的話,那麼你也應該對鎖定的影響進行整理。

請注意,SQL Server可以爲給定查詢建議索引by executing the query in SQL Server Management Studio或通過Database Engine Tuning Advisor。您應該這樣做以確保您沒有刪除SQL Server正在使用的索引來加速INSERT

如果這仍然不夠快,那麼你應該考慮分組了使用BULK INSERT的,而不是插入(或類似的bcp utilitySqlBulkCopy,它們都使用BULK INSERT下蓋)。這會在插入行時提供最高的吞吐量。

另請參閱Optimizing Bulk Import Performance - 該文章中的大部分建議也適用於「常規」插入。

+0

正如我所說我只有一個索引是主鍵而沒有觸發器。我將嘗試使用BULK INSERT方法。 –

+0

將源查詢排序到目標上的聚簇索引。 – Paparazzi

+0

而不是將恢復模型更改爲簡單,請將其更改爲[BULK_LOGGED](http://msdn.microsoft.com/en-us/library/ms189275(v = sql.110).aspx)。批量操作後您可以將其更改回來。 – CFreitas

1

你有沒有考慮過使用SqlBulkCopy?您需要構建一個DataTable並將其傳遞給WriteToServer例程。

它快!

1

可以結束

OPTION(RECOMPILE)