使用 IEnumerable SqlDataRecord 的示例
它的工作原理有点像反向数据读取器
注意我排序。这是通过聚集索引实现的。索引碎片绝对会降低加载速度。第一个实现使用插入值(未排序),在 12 小时的运行中,这个版本实际上快了 100 倍。我还禁用了 PK 以外的索引,并在加载结束时重新索引。从长远来看,我每秒可以获得大约 500 行。你的样本是 1400/秒,太棒了。如果您开始看到退化,那么就需要注意了。
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());
}
}
其他需要考虑的工具是 SQLBulkCopy .NET 类和 Drapper。
OP问如何批量执行。
while (true)
{
// if no more break;
// fill list or datatable with next 100000
// send list or datatable to db
}