Le moyen le plus rapide d'insérer 30 000 lignes dans une table temporaire sur SQL Server avec C #

J'essaie de trouver comment je peux améliorer ma performance de l'insert dans une table temporaire dans SQL Server à l'aide de c#. Certaines personnes disent que je devrais utiliser SQLBulkCopy mais je dois faire quelque chose de mal, comme il semble fonctionner beaucoup plus lent que de construire un SQL insert chaîne à la place.

Mon code pour créer la table à l'aide de SQLBulkCopy est ci-dessous:

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);

        }
    }

De cette façon, mes inserts de prendre du temps pour s'exécuter. J'ai obtenu mon insère plus rapide de travailler d'une autre manière:

J'ai créé les inserts peu comme une chaîne de caractères et la rejoint dans mon SQL create table temp déclaration:

Création de plaquettes de chaîne:

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;

    }

De les utiliser dans l'instruction SQL après la création de la requête:

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);
...

Depuis que j'ai vu des gens qui me disent (sur stack exchange https://dba.stackexchange.com/questions/44217/fastest-way-to-insert-30-thousand-rows-in-sql-server/44222?noredirect=1#comment78137_44222 ) Que je devrais utiliser SQLBulkCopy et qui serait plus rapide je crois que je devrais améliorer la façon dont je le fais. Donc, si quelqu'un peut suggérer comment je peux améliorer mon SQLBulkCopy code OU me dire si il y a une meilleure instruction insert qui peut améliorer mes performances de l'application de ce serait génial.

source d'informationauteur Jenninha