如何将dataAdapter.updateBatchSize设置为“最佳”值?
-
01-10-2019 - |
题
我终于插入了批处理工作,现在我一直在摆弄批次的大小,但是我看不到50和10000的价值之间的性能差异。这似乎很奇怪我,但我不知道现场发生了什么,所以这可能是正常的行为。
我将160k行插入表中,而测试值的平均时间为115 +/- 2秒。如果不进行批处理,则需要210秒,因此我对改进非常满意。目标表是:
CREATE TABLE [dbo].[p_DataIdeas](
[wave] [int] NOT NULL,
[idnumber] [int] NOT NULL,
[ideaID] [int] NOT NULL,
[haveSeen] [bit] NOT NULL CONSTRAINT [DF_p_DataIdeas_haveSeen] DEFAULT ((0)),
CONSTRAINT [PK_p_DataIdeas] PRIMARY KEY CLUSTERED
(
[wave] ASC,
[idnumber] ASC,
[ideaID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
我读 设置UpdateBatchSize时要寻找什么 答案是简单地测试几个不同的值。我能理解这一点,但是如果您知道表设计,SQL问题和即将插入的数据,是否应该计算或至少猜测一个好价值?
有人可以推荐任何最佳实践吗?
解决方案
您可以通过查看SQL Profiler或致电来查看批处理的效果 SqlConnection.RetrieveStatistics()
. 。您应该看到的是,每批对应于DB的单个往返。
至于如何优化批次大小,一个非常粗略的大多数规则是,性能往往会停止改进,批量大小以上约50个 - 实际上,有时较大的批次比较小的批次更慢。如果我太忙而无法测试,我通常会从大约20个开始(除非我使用的是有价值的参数,否则最多500批次的速度比较小的参数更快)。但是,最佳数字取决于插入的总尺寸(它们都适合RAM),您的DB日志所在的磁盘的速度,是否在其自己的驱动器/LUN上(该日志)(如果不是),那么大的成本),等等。
可实现的速度通常首先受到往返数量的限制,然后是交易大小,然后是记录磁盘速度(尤其是顺序访问是否可能是可能的,或者由于同一纺锤体上的其他文件而被迫随机访问),最后内存。但是,所有因素在一定程度上也相关。
改进插入物的过程的第一步是在交易中进行交易 - 也许每批或两批交易。除此之外,表值参数可能是下一步,使用带有的存储过程 INSERT INTO Table SELECT column FROM @TableArgument
.
其他提示
尽管更改updateBatchSize将在某种程度上有所帮助,但使用DataAdapter更新许多记录的基本方法将很慢。这是因为最终,DataAdapter将为每一行生成一个单独的SQL语句(插入,更新或删除)。 updateBatchSize仅影响发送到SQL Server的一个TSQL批次发送的这些单独的语句中的数量。
为了获得更大的性能改进,您希望SQLServer在一个语句中插入/Update/删除许多记录(通常使用某种连接)。表有价值的参数(如Ricknz所述)是一种方法。另一种可能性是使用sqlbulkcopy(尽管通常需要为此使用登台表)。
确保还有一项主动交易,它将大大提高性能(在我的测试中使用MySqlDataAdapter中约为30倍)。