SQL加快插入的性能?
Posted
技术标签:
【中文标题】SQL加快插入的性能?【英文标题】:SQL speed up performance of insert? 【发布时间】:2011-10-28 17:57:27 【问题描述】:我正在对 sql server 进行一些测试,我希望获得尽可能好的插入速度。 我使用的语句是这样的:
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 类型。
我从目标表中删除了所有索引,除了作为标识字段的主键。
关于如何进一步提高性能的任何提示?
附:在这种形式中,我的平均速度为 16.000 行/秒。
【问题讨论】:
dbo.udf_convert_hex_to_dec
正在杀死你。您使用的是哪个版本的 SQL Server?有内置插件可以进行这种转换。
我怀疑地看着udf_convert_hex_to_dec
函数。插入只能在一定程度上更快,一些因素是索引和物理 IO 性能。对它运行一个查询分析器,我敢打赌选择是因为这个功能很慢。
用户定义的函数可能很慢。您不能将十六进制直接转换为十进制 - 例如 CAST (col9 AS Decimal(4)) >?
select 的成本是 9% table spool 的成本是 32% cluster insert 成本是 58%
【参考方案1】:
要获得可能的最佳性能,您应该:
删除表上的所有触发器和约束 删除所有索引,插入需要的索引除外 确保您的聚集索引始终在表的末尾插入新记录(标识列就可以了)。这可以防止页面拆分(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 utility 或SqlBulkCopy
,两者都在封面下使用BULK INSERT
)。这将在插入行时提供最高的吞吐量。
另请参阅Optimizing Bulk Import Performance - 该文章中的大部分建议也适用于“正常”插入。
【讨论】:
正如我所说,我只有一个索引,它是主键,没有触发器。我将尝试使用 BULK INSERT 方法。 将源查询排序到目标上的聚集索引。 不要将恢复模式更改为简单,而是将其更改为BULK_LOGGED。批量操作后可以改回来。 我正在测试这个。设置填充因子似乎会减慢插入速度。直觉上这是有道理的。我猜(没有检查),这样数据会占用更少的磁盘空间......【参考方案2】:您是否考虑过使用 SqlBulkCopy?您需要构建一个 DataTable 并将其传递给 WriteToServer 例程。
太快了!
【讨论】:
【参考方案3】:您可以在结束前在您的存储过程中使用
OPTION(RECOMPILE)
【讨论】:
以上是关于SQL加快插入的性能?的主要内容,如果未能解决你的问题,请参考以下文章