.net 表值参数:以小块发送数据
我从csv文件中读取数据,并将数据作为表变量发送到存储过程。根据我目前的测试,我能够在3分30秒内处理300k记录。该文件可能包含多达数百万条记录。我想知道一次性将所有这些记录发送到存储过程是个好主意,还是应该成批发送,比如500k?我已将命令超时设置为1800。使用IEnumerable SqlDataRecord的示例.net 表值参数:以小块发送数据,.net,sql-server-2008,stored-procedures,table-variable,.net,Sql Server 2008,Stored Procedures,Table Variable,我从csv文件中读取数据,并将数据作为表变量发送到存储过程。根据我目前的测试,我能够在3分30秒内处理300k记录。该文件可能包含多达数百万条记录。我想知道一次性将所有这些记录发送到存储过程是个好主意,还是应该成批发送,比如500k?我已将命令超时设置为1800。使用IEnumerable SqlDataRecord的示例 它的工作原理有点像反向数据读取器 注意我的分类。这是通过聚集索引实现的。索引的碎片化将彻底扼杀加载速度。第一个实现使用了插入值(未排序),在12小时的运行中,这个版本的速度实
它的工作原理有点像反向数据读取器 注意我的分类。这是通过聚集索引实现的。索引的碎片化将彻底扼杀加载速度。第一个实现使用了插入值(未排序),在12小时的运行中,这个版本的速度实际上快了100倍。在加载结束时,我还禁用了PK和reindex之外的索引。从长远来看,我得到了大约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());
}
}
您是指表变量还是表值参数?是的,您是对的,我正在使用TVP将数据发送到存储过程。我想@MartinSmith发布了一些关于传递到TVP的最佳行数阈值的信息,但我现在很难找到他的帖子。我用TVP加载数据,但我认为你不需要分解它。如果你追踪它,它似乎一次只处理一个。你是如何实施的?您使用的是实现IEnumerable的类吗?我发现更快的数据表和更少的内存。@AaronBertrand如果你指的是插入值。谢谢你,我真的测试过了,非常有效。但是DBA和管理层希望我每个请求发送10万条记录。你知道我们怎么处理吗?我的意思是向datatable发送100K请求,或者如何发送?请参阅问题末尾的更新。请求不是正确的术语。这是插页。TVP实现将一次发送一条插入记录,而不管批大小如何。你已经说过你在SQL分析器中看到了。是的,@Blam谢谢你纠正我。我是新手,非常感谢你的帮助。因此,问题是C#是否有一种方法可以将100k插入发送到TVP?我最终使用了以下建议的方法:
while (true)
{
// if no more break;
// fill list or datatable with next 100000
// send list or datatable to db
}