Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Paramètre de valeur de table :envoi de données en petits morceaux

Un exemple d'utilisation de IEnumerable SqlDataRecord
Cela fonctionne un peu comme un lecteur de données inversé

Remarquez que je trie. C'est par l'index clusterisé. La fragmentation des index tuera absolument la vitesse de chargement. La première implémentation utilisait Insérer des valeurs (non triées) et en 12 heures, cette version est littéralement 100 fois plus rapide. Je désactive également les index autres que le PK et réindexe à la fin du chargement. À long terme, j'obtiens environ 500 lignes / seconde. Votre échantillon est de 1400 / seconde donc super. Si vous commencez à voir une dégradation, alors les choses à regarder.

public class DocFTSinXsCollection : List<DocFTSinX>, IEnumerable<SqlDataRecord>
{
    // used by TVP for fast insert
    private int sID;
    private IEnumerable<DocFTSinX> docFTSinXs;
    IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
    {
        //todo fix the order in 3 to sID, wordID1, workID2
        var sdr = new SqlDataRecord(
        new SqlMetaData("wordID1", System.Data.SqlDbType.Int),
        new SqlMetaData("wordID2", System.Data.SqlDbType.Int),
        new SqlMetaData("sID", System.Data.SqlDbType.Int),
        new SqlMetaData("Delta", System.Data.SqlDbType.Int));
        foreach (DocFTSinX oh in docFTSinXs.OrderBy(x => x.Word1).ThenBy(x => x.Word2))
        {
            sdr.SetInt32(0, oh.Word1);
            sdr.SetInt32(1, oh.Word2);
            sdr.SetInt32(2, sID);
            sdr.SetInt32(3, (Int32)oh.Delta);
            yield return sdr;
        }
    }

    public DocFTSinXsCollection(int SID, IEnumerable<DocFTSinX> DocFTSinXs)
    {
        sID = SID;
        docFTSinXs = DocFTSinXs;
        //Debug.WriteLine("DocFTSinXsCollection DocFTSinXs " + DocFTSinXs.Count().ToString());
    }
}

D'autres outils à considérer sont la classe SQLBulkCopy .NET et Drapper.

OP a demandé comment effectuer des lots.

 while (true)
 {
     // if no more break;
     // fill list or datatable with next 100000
     // send list or datatable to db
 }