Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SQL Server+循环插入性能_C#_Sql_Sql Server 2008 R2 - Fatal编程技术网

C# SQL Server+循环插入性能

C# SQL Server+循环插入性能,c#,sql,sql-server-2008-r2,C#,Sql,Sql Server 2008 R2,我正在做一个循环插入,如下面的方法a所示,似乎用每个循环调用数据库不是一个好主意。我发现另一种方法是在存储过程中循环一个逗号分隔的字符串,而不是执行插入操作,这样数据库就只有一个条目。在绩效方面是否会有任何重大改进?: 方法A: 方法B: 方法B存储过程/在存储过程中执行循环插入 如果您希望使用给定类型的多个输入值获得更好的插入性能,我建议您查看 可以找到一个示例,其中显示了一些使用它们的示例代码。更少的查询通常意味着更快的处理。也就是说,我的一位同事在.NET Framework的TSQL批量

我正在做一个循环插入,如下面的方法a所示,似乎用每个循环调用数据库不是一个好主意。我发现另一种方法是在存储过程中循环一个逗号分隔的字符串,而不是执行插入操作,这样数据库就只有一个条目。在绩效方面是否会有任何重大改进?:

方法A:

方法B:

方法B存储过程/在存储过程中执行循环插入


如果您希望使用给定类型的多个输入值获得更好的插入性能,我建议您查看


可以找到一个示例,其中显示了一些使用它们的示例代码。

更少的查询通常意味着更快的处理。也就是说,我的一位同事在.NET Framework的TSQL批量插入包装器方面取得了一些成功,该包装器由框架作为SqlBulkCopy提供。

主要API示例取自链接文章,它将数据表的内容写入SQL:

private void WriteToDatabase()
{
    // get your connection string
    string connString = "";
    // connect to SQL
    using (SqlConnection connection = 
            new SqlConnection(connString))
    {
        // make sure to enable triggers
        // more on triggers in next post
        SqlBulkCopy bulkCopy = 
            new SqlBulkCopy
            (
            connection, 
            SqlBulkCopyOptions.TableLock | 
            SqlBulkCopyOptions.FireTriggers | 
            SqlBulkCopyOptions.UseInternalTransaction,
            null
            );

        // set the destination table name
        bulkCopy.DestinationTableName = this.tableName;
        connection.Open();

        // write the data in the "dataTable"
        bulkCopy.WriteToServer(dataTable);
        connection.Close();
    }
    // reset
    this.dataTable.Clear();
    this.recordCount = 0;
}

链接的文章解释了利用这种机制需要做些什么。

您可以为此使用批量插入功能


查看此博客了解详细信息:

根据我的经验,有三件事你不想为每条记录做:

每行打开/关闭一个sql连接。此问题由ADO.NET连接池处理。除非禁用了池,否则您不必担心它

每行数据库往返。这与网络带宽或网络延迟有关,而与客户端线程睡眠有关。每次客户端醒来或浪费时间时,您都希望客户端有大量的工作要做

每行打开/关闭sql事务日志。打开和关闭日志不是免费的,但您也不想让它打开太久。在一个事务中执行多个插入,但不要太多

在其中任何一个方面,您可能会看到很多改进,从每个请求1行到每个请求10行。您可以通过在传输批处理之前在客户端构建10条insert语句来实现这一点


您将列表发送到进程的方法已经被写得非常深入。

我假设是SQL Server-如果是,是哪个版本?它是SQL Server 2008R20您也可以使用方法B+XML以行形式返回CSV值,而不进行循环,然后插入表SELECT*FROM。。。
string UserIds = "Tom, Jerry, 007"; // Assuming we already concatenate the strings. So no loops this time here.
userBll = new UserBLL();  
// Call userBll method to insert into SQL Server with 'UserIds' as parameter.
if right(rtrim(@UserIds ), 1) <> ','
    SELECT @string = @UserIds + ','

SELECT @pos =  patindex('%,%' , @UserIds )

while @pos <> 0 
begin
    SELECT @piece = left(@v, (@pos-1))

    -- Perform the insert here

    SELECT @UserIds = stuff(@string, 1, @pos, '')
    SELECT @pos =  patindex('%,%' , @UserIds )
end
private void WriteToDatabase()
{
    // get your connection string
    string connString = "";
    // connect to SQL
    using (SqlConnection connection = 
            new SqlConnection(connString))
    {
        // make sure to enable triggers
        // more on triggers in next post
        SqlBulkCopy bulkCopy = 
            new SqlBulkCopy
            (
            connection, 
            SqlBulkCopyOptions.TableLock | 
            SqlBulkCopyOptions.FireTriggers | 
            SqlBulkCopyOptions.UseInternalTransaction,
            null
            );

        // set the destination table name
        bulkCopy.DestinationTableName = this.tableName;
        connection.Open();

        // write the data in the "dataTable"
        bulkCopy.WriteToServer(dataTable);
        connection.Close();
    }
    // reset
    this.dataTable.Clear();
    this.recordCount = 0;
}