Un exemple d'utilisation de IEnumerable SqlDataRecord
Cela fonctionne un peu comme un lecteur de données inversé
Remarquez que je trie. C'est par l'index clusterisé. La fragmentation des index tuera absolument la vitesse de chargement. La première implémentation utilisait Insérer des valeurs (non triées) et en 12 heures, cette version est littéralement 100 fois plus rapide. Je désactive également les index autres que le PK et réindexe à la fin du chargement. À long terme, j'obtiens environ 500 lignes / seconde. Votre échantillon est de 1400 / seconde donc super. Si vous commencez à voir une dégradation, alors les choses à regarder.
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());
}
}
D'autres outils à considérer sont la classe SQLBulkCopy .NET et Drapper.
OP a demandé comment effectuer des lots.
while (true)
{
// if no more break;
// fill list or datatable with next 100000
// send list or datatable to db
}