我正在尝试找出如何使用 c# 在 SQL Server 的临时表中提高插入性能。有些人说我应该使用 SQLBulkCopy 但是我一定做错了,因为它似乎比简单地构建 SQL 插入字符串要慢得多。
我使用 SQLBulkCopy 创建表的代码如下:
public void MakeTable(string tableName, List<string> ids, SqlConnection connection)
    {
        SqlCommand cmd = new SqlCommand("CREATE TABLE ##" + tableName + " (ID int)", connection);
        cmd.ExecuteNonQuery();
        DataTable localTempTable = new DataTable(tableName);
        DataColumn id = new DataColumn();
        id.DataType = System.Type.GetType("System.Int32");
        id.ColumnName = "ID";
        localTempTable.Columns.Add(id);
        foreach (var item in ids)
        {
             DataRow row = localTempTable.NewRow();
             row[0] = item;
             localTempTable.Rows.Add(row);
             localTempTable.AcceptChanges();
        }
        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
        {
            bulkCopy.DestinationTableName = "##" + tableName;
            bulkCopy.WriteToServer(localTempTable);
        }
    }
这样我的插入需要很长时间才能运行。我让我的插入以另一种方式更快地工作:
我将插入位创建为字符串,并将其加入到我的 SQL 创建临时表语句中:
插入字符串的创建:
public string prepareInserts(string tableName, List<string> ids)
    {
        List<string> inserts = new List<string>();
        var total = ids.Select(p => p).Count();
        var size = 1000;
        var insert = 1;
        var skip = size * (insert - 1);
        var canPage = skip < total;
        while (canPage)
        {
            inserts.Add(" insert into ##" + tableName + @" (ID) values " + String.Join(",", ids.Select(p => string.Format("({0})", p))
                        .Skip(skip)
                        .Take(size)
                        .ToArray()));
            insert++;
            skip = size * (insert - 1);
            canPage = skip < total;
        }
        string joinedInserts = String.Join("\r\n", inserts.ToArray());
        return joinedInserts;
    }
创建查询后在 SQL 语句中使用它们:
inserts = prepareInserts(tableName, ids);
var query = @"IF EXISTS
                                            (
                                            SELECT *
                                            FROM tempdb.dbo.sysobjects
                                            WHERE ID = OBJECT_ID(N'tempdb..##" + tableName + @"')
                                            )
                                                BEGIN
                                                    DELETE FROM ##" + tableName + @"
                                                END
                                            ELSE
                                                BEGIN
                                                    CREATE TABLE ##" + tableName + @"
                                                    (ID int)
                                                END " + inserts;
            var command = new SqlCommand(query, sqlConnection);
...
因为我看到人们告诉我(在堆栈交换https://dba.stackexchange.com/questions/44217/fastest-way-to-insert-30-thousand-rows-in-sql-server/44222?noredirect= 1#comment78137_44222 ) 我应该使用 SQLBulkCopy,这样会更快,我相信我应该改进我的做法。因此,如果有人可以建议我如何改进我的 SQLBulkCopy 代码,或者告诉我是否有更好的插入语句可以提高我的应用程序的性能,那就太好了。

