Optimisation C #: insertion de 200 millions de lignes dans la base de données

c# datatable sqlbulkcopy

Question

J'ai le code suivant (simplifié) que j'aimerais optimiser pour la vitesse:

long inputLen = 50000000; // 50 million 
DataTable dataTable = new DataTable();
DataRow dataRow;
object[] objectRow;
while (inputLen--)
{
    objectRow[0] = ...
    objectRow[1] = ...
    objectRow[2] = ...

    // Generate output for this input
    output = ...

    for (int i = 0; i < outputLen; i++) // outputLen can range from 1 to 20,000
    {
         objectRow[3] = output[i];
         dataRow = dataTable.NewRow();
         dataRow.ItemArray = objectRow;
         dataTable.Rows.Add(dataRow);
    }
}

// Bulk copy
SqlBulkCopy bulkTask = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null);
bulkTask.DestinationTableName = "newTable";
bulkTask.BatchSize = dataTable.Rows.Count;
bulkTask.WriteToServer(dataTable);
bulkTask.Close();

J'utilise déjà SQLBulkCopy pour tenter d'accélérer les choses, mais il semble que l'attribution de valeurs au DataTable lui-même s'avère lente.

Je ne sais pas comment les DataTables fonctionnent, alors je me demande si je crée une surcharge inutile en créant d'abord un tableau réutilisable, puis en l'assignant à un DataRow, puis en ajoutant le DataRow au DataTable? Ou l'utilisation de DataTable n'est-elle pas optimale au départ? L'entrée provient d'une base de données.

Je me fiche de LOC, mais de la vitesse. Quelqu'un peut-il donner des conseils à ce sujet?

Réponse acceptée

Pour une si grande table, vous devriez plutôt utiliser le

public void WriteToServer(IDataReader reader)

méthode.

Cela signifie peut-être que vous devrez implémenter vous-même une "fausse" interface IDataReader avec votre code (si vous ne récupérez pas les données d'un IDataReader existant), mais vous obtiendrez ainsi le "streaming" de bout en bout et évitera une boucle de 200 millions.


Réponse populaire

Au lieu de IDataReader en mémoire une énorme table de données, je suggérerais de mettre en place un IDataReader qui sert les données au fur et à mesure que la copie en bloc disparaît. Cela réduira le besoin de tout garder en mémoire à l’avance et devrait donc servir à améliorer les performances.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi