Een voorbeeld van het gebruik van IEnumerable SqlDataRecord
Het werkt een beetje als een reverse datareader
Merk op dat ik sorteer. Dit is door de geclusterde index. Fragmentatie van de indexen zal de laadsnelheid absoluut doden. De eerste implementatie gebruikte Insert Values (ongesorteerd) en in een 12 uur durende run is deze versie letterlijk 100x sneller. Ik schakel ook andere indexen uit dan de PK en herindexeer aan het einde van de belasting. Op de lange termijn krijg ik ongeveer 500 rijen / seconde. Je steekproef is 1400 / seconde zo geweldig. Als je degradatie begint te zien, dan zijn er dingen om naar te kijken.
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 hulpmiddelen om te overwegen zijn de SQLBulkCopy .NET-klasse en Drapper.
OP vroeg hoe te presteren in batches.
while (true)
{
// if no more break;
// fill list or datatable with next 100000
// send list or datatable to db
}