2011-08-17 203 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)