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 插入后无法获取行

C# SQLDataAdapter - 不将数据插入数据库

SqlDataAdapter 更新插入 与 InsertBulkCopy

成功插入期间 SqlDataAdapter 未触发 RowUpdated 或 RowUpdating

SqlDataAdapter.Update(dataset) 方法插入新行但不更新现有行

.Net SqlDataAdapter 在使用列上的默认值插入后检索身份