Et eksempel på brug af IEnumerable SqlDataRecord
Det fungerer ligesom en omvendt datalæser
Bemærk, at jeg sorterer. Dette er ved det klyngede indeks. Fragmentering af indekserne vil absolut dræbe belastningshastigheden. Den første implementering brugte Insert Values (usorteret), og på 12 timer er denne version bogstaveligt talt 100x hurtigere. Jeg deaktiverer også andre indekser end PK og genindekserer ved slutningen af belastningen. På lang sigt får jeg omkring 500 rækker/sekund. Din prøve er 1400 / sekund så stor. Hvis du begynder at se nedbrydning, så ting at se på.
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());
}
}
Andre værktøjer at overveje er SQLBulkCopy .NET-klassen og Drapper.
OP spurgte, hvordan man optræder i batches.
while (true)
{
// if no more break;
// fill list or datatable with next 100000
// send list or datatable to db
}