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
}