Przykład użycia IEnumerable SqlDataRecord
Działa trochę jak odwrócony czytnik danych
Zauważ, że sortuję. Jest to indeks klastrowy. Fragmentacja indeksów całkowicie zabije prędkość ładowania. Pierwsza implementacja wykorzystywała Wstaw wartości (nieposortowane) iw ciągu 12 godzin ta wersja jest dosłownie 100x szybsza. Wyłączam również indeksy inne niż PK i ponownie indeksuję na końcu obciążenia. Na dłuższą metę dostaję około 500 rzędów na sekundę. Twoja próbka to 1400 / sekundę, więc świetna. Jeśli zaczniesz dostrzegać degradację, to na co zwrócić uwagę.
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());
}
}
Inne narzędzia do rozważenia to klasa SQLBulkCopy .NET i Drapper.
OP zapytał, jak wykonać w partiach.
while (true)
{
// if no more break;
// fill list or datatable with next 100000
// send list or datatable to db
}