SqlDataAdapter 插入性能不佳
Posted
技术标签:
【中文标题】SqlDataAdapter 插入性能不佳【英文标题】:SqlDataAdapter Insert poor performance 【发布时间】:2013-07-30 19:48:31 【问题描述】:我编写了一些工资单处理软件,最终使用SqlDataAdapter.Insert()
将数据写入 SQL Server 表。 (我使用的是使用SqlCommandBuilder()
创建的默认插入命令。)我在 Windows 7 上使用 .NET Framework 4,写入 SQL Server 2008(不是 R2)Std Edition x64 SP3。问题是,我只看到从我的 PC(Dell Optiplex 990 Core i7)到 SQL Server(我的 PC 和服务器上的 NIC 是 GB Enet,但不幸的瓶颈之间有一些 100Mbps 的交换机)的吞吐量约为 2 Mbps,但仍然 - 100Mbps)。我可以将文件从我的 PC 复制到运行 SQL Server 的服务器,并且没有吞吐量问题 - 我可以在那里获得非常接近 100 Mbps 的吞吐量。我将数据库放在另一个运行 2008 R2 的 LAN SQL Server 上,在那里我设法获得了 5 Mbps 的吞吐量,但仍然 - 非常慢。 Insert()
命令运行时,我的 PC 的 CPU 接近 0。我尝试增加和减少 SqlConnection.ConnectionString
属性中的 Packet Size 参数,但没有任何效果。
如果我从我的 PC 上的 SSMS 到有问题的 SQL Server 执行SELECT * FROM <table>
,我可以获得大约 45 Mbps 的持续吞吐量。
我不确定下一步该去哪里寻找罪魁祸首 - 任何建议表示赞赏。
【问题讨论】:
执行更新时修改了多少行? Update 命令仅处理更改的行。另外,您为什么要使用Select * from <table>
而不是Select * from <table> where filterColumn = @filter
如果您要查询足够多的行以最大限度地利用您的网卡,您可能可以优化查询。
@ScottChamberlain - 总脑动脉瘤 - 我的意思是真的Insert()
。问题已解决。
好的,你一次插入多少行?
@ScottChamberlain 在 2000-4000 之间。
哦,是的,你绝对不应该使用Insert()
,那会生成 2000-4000 个单独的 INSERT INTO
语句。每条语句都需要 SQL Server 执行诸如检查其唯一键冲突之类的操作。请参阅我关于如何使用 SqlBulkCopy 的答案,它相当于 SQL 的 BULK INSERT
,因此它会在每个批次结束时执行一次这些约束检查(默认批次大小为“无限”,但可调整)
【参考方案1】:
SqlDataAdapter 的 Insert 一次只执行一条记录,如果您要插入大量记录,则应该使用 SqlBulkCopy 来减少执行这些插入的开销。
using (SqlConnection destinationConnection = new SqlConnection(connectionString))
destinationConnection.Open();
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(destinationConnection))
bulkCopy.DestinationTableName = destTableName;
bulkCopy.WriteToServer(sourceDataTable);
【讨论】:
非常感谢 - 这正是我想要的。以上是关于SqlDataAdapter 插入性能不佳的主要内容,如果未能解决你的问题,请参考以下文章
SqlDataAdapter 更新插入 与 InsertBulkCopy
成功插入期间 SqlDataAdapter 未触发 RowUpdated 或 RowUpdating