百万次插入:SqlBulkCopy 超时

Posted

技术标签:

【中文标题】百万次插入:SqlBulkCopy 超时【英文标题】:Million inserts: SqlBulkCopy timeout 【发布时间】:2015-02-07 18:15:11 【问题描述】:

我们已经有一个正在运行的系统来处理所有连接字符串(db2oracleMSServer)。

目前,我们正在使用ExecuteNonQuery() 进行一些插入操作。

我们希望通过使用SqlBulkCopy() 而不是ExecuteNonQuery() 来提高性能。我们有一些客户拥有超过 5000 万条记录。

我们不想使用 SSIS,因为我们的系统支持多个数据库。

我创建了一个示例项目来测试SqlBulkCopy() 的性能。我为 MSServer

创建了一个简单的读取和插入函数

这是小函数:

public void insertIntoSQLServer()

    using (SqlConnection SourceConnection = new SqlConnection(_sourceConnectionString))
    
        //Open the connection to get the data from the source table
        SourceConnection.Open();
        using (SqlCommand command = new SqlCommand("select * from " + _sourceSchemaName + "." + _sourceTableName + ";", SourceConnection))
        
            //Read from the source table
            command.CommandTimeout = 2400;
            SqlDataReader reader = command.ExecuteReader();

            using (SqlConnection DestinationConnection = new SqlConnection(_destinationConnectionString))
            
                DestinationConnection.Open();
                //Clean the destination table
                new SqlCommand("delete from " + _destinationSchemaName + "." + _destinationTableName + ";", DestinationConnection).ExecuteNonQuery();

                using (SqlBulkCopy bc = new SqlBulkCopy(DestinationConnection))
                
                    bc.DestinationTableName = string.Format("[0].[1]", _destinationSchemaName, _destinationTableName);
                    bc.NotifyAfter = 10000;
                    //bc.SqlRowsCopied += bc_SqlRowsCopied;
                    bc.WriteToServer(reader);
                
            
        
    

当我的 dummyTable 中的数据少于 200 000 时,批量复制工作正常。但是,当记录超过 200 000 条时,出现以下错误:

尝试对具有挂起操作的对象调用大容量复制。

等待操作超时(对于 IDataReader)

我为读者增加了 CommandTimeout。好像解决了IDataReader相关的超时问题。

我在代码中做错了吗?

【问题讨论】:

永远不要 SqlBulkCopy 到目标表。那东西严重破坏了锁定密码。特别是在使用多线程时。创建一个临时表,插入其中,然后复制到目标表。 我没有使用多线程。我总是插入一个空表。 为什么要使用 sqlbulkcopy?严重地。同一数据库上的表 - 只需告诉服务器复制数据而不是将其拉到您的程序中只是为了上传它。用一条语句直接选择目标表。 它们不会在同一台服务器上...我将从多个数据库中读取数据,例如 db2、oracle、sql server、mysql。现在我们正在使用它,就像你说的那样。但由于我们需要支持多个数据库,我们正在探索新的可能性。 【参考方案1】:

您能否尝试在调用 WriteToServer 之前添加以下内容...

bc.BatchSize = 10000;
bc.BulkCopyTimeout = 0;

我不知道默认的批量大小或超时时间是多少,但我怀疑这可能是您的问题。 希望有帮助

此外,您可以尝试使用不同的 Batch Size 以获得最佳性能。

【讨论】:

在为BulkCopyTimeout 举例时指定 0 的含义(无穷大) 默认 BatchSize 为零(每个 WriteToServer 是一个批次),默认 BulkCopyTimeout 为 30(秒)【参考方案2】:

你可以试试这个

bc.BatchSize = 100000; // How many Rows you want to insert at a time
bc.BulkCopyTimeout = 60; // Time in Seconds. If you want infinite waiting Time then assign 0.

【讨论】:

逗号在 c# 整数文字中无效 @JJS 下划线是,并且可以用来代替千位分隔符以提高可读性。

以上是关于百万次插入:SqlBulkCopy 超时的主要内容,如果未能解决你的问题,请参考以下文章

C#百万数据查询超时问题

并查集详解

并查集 路径压缩

SQL Server 2008 R2 的可重试 SQLBulkCopy

SQL Server 简单插入语句超时

检测到 Sqoop 套接字超时:从大型机读取数据并插入 Hive 时读取超时