Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Tabellenwertparameter:Senden von Daten in kleinen Blöcken

Ein Beispiel für die Verwendung von IEnumerable SqlDataRecord
Es funktioniert wie ein umgekehrter Datenleser

Beachten Sie, dass ich sortiere. Dies geschieht durch den gruppierten Index. Die Fragmentierung der Indizes wird die Ladegeschwindigkeit absolut beeinträchtigen. Die erste Implementierung verwendete Werte einfügen (unsortiert) und in einem 12-Stunden-Lauf ist diese Version buchstäblich 100x schneller. Ich deaktiviere auch andere Indizes als den PK und indiziere am Ende des Ladevorgangs neu. Auf lange Sicht bekomme ich etwa 500 Zeilen / Sekunde. Deine Probe ist mit 1400/Sekunde so toll. Wenn Sie anfangen, eine Verschlechterung zu sehen, sollten Sie sich die Dinge ansehen.

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

Andere zu berücksichtigende Tools sind die .NET-Klasse SQLBulkCopy und Drapper.

OP hat gefragt, wie man in Stapeln arbeitet.

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