Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Parametro con valori di tabella:invio di dati in piccoli blocchi

Un esempio di utilizzo di IEnumerable SqlDataRecord
Funziona un po' come un lettore di dati inverso

Nota che ordinamento. Questo è dall'indice cluster. La frammentazione degli indici ucciderà assolutamente la velocità di caricamento. La prima implementazione utilizzava i valori di inserimento (non ordinati) e in 12 ore di esecuzione questa versione è letteralmente 100 volte più veloce. Disattivo anche gli indici diversi da PK e reindex alla fine del caricamento. A lungo termine sto ottenendo circa 500 righe/secondo. Il tuo campione è 1400 / secondo così grande. Se inizi a vedere il degrado, allora le cose da guardare.

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

Altri strumenti da considerare sono la classe SQLBulkCopy .NET e Drapper.

OP ha chiesto come eseguire in batch.

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