想要了解在C# / ADO.NET中实现这一目标的最佳/优化方法的意见?
请注意:提取逻辑不能是SQL的一部分。该逻辑嵌入在COM DLL中,我正在从.NET进行互操作,并将其应用于Col1列的值以生成一个新值,最终必须将其保存在T1.Col2中。
由于您需要通过COM对象传输数据进行某些操作,这是我会做的事情:
使用内存较大的机器-将数据分块加载到内存中(例如每次5000或50000行),处理它并在SQL Server上进行更新...
对于UPDATE部分,请使用事务,并将5000-20000个UPDATE放入一个事务中...
[编辑]:通过适当地分区工作并将500000或1000000行分配给一个“工作机器”,您可以将其加速到SQL Server的最大限制... [/编辑]
另一种选择-虽然不建议(仅因为在此特定情况下由COM对象引入的理论上可能存在的安全和/或稳定性问题):
尽管这是关于SQL Server的描述,但在Windows上使用Oracle也有类似的可能性
您可以通过编写和安装公开存储过程的.NET程序集,将此转换的逻辑放入SQL Server中,以调用执行转换... .NET程序集反过来访问该COM对象... 如何请参见http://www.sqlteam.com/article/writing-clr-stored-procedures-in-charp-introduction-to-charp-part-1
此内容的MSDN参考链接为http://msdn.microsoft.com/en-us/library/ms131094.aspx
UPDATE T1
SET col2 = [some function based on col1]
请注意,根据数据库平台的不同,这可能会导致事务日志爆炸。对于 MS SQL,我建议您每次以较小的批量进行更新,例如100K行或更少。
如果函数逻辑过于复杂,则请确保您基于主键发出所有500万个更新:
UPDATE T1
SET col2 = @newval
WHERE tableID = @id
update t2
set col2 = 1234 -- the computed value over all rows in t1
select t1.col1,
t2.col2
from t1
cross join t2 -- t2 only has 1 row
更新操作相对较为昂贵,写入一行数据肯定比写入五百万行要便宜得多。
否则我会把磨坊建在木材堆旁,所以如果可能的话请使用TSQL。不过,500万行也不是什么大问题,您能够在服务器上处理它们吗?还是需要通过网络传输?如果是后者,那么成本就会增加。
敬礼,Gert-Jan
一次性在内存中拥有如此多的数据是很多的。如果可能的话,我建议从COM DLL中以较小的记录批量获取数据并处理。使用PLinq to objects可以让您最大化处理器使用率。两者之间,您应该能够找到一个良好的平衡点。
一些基本指针:
如果这只是一次性的操作,那么将您的500万+记录转储到文件中。运行逻辑以生成新记录。 转储和文件逻辑应该快速且不耗时。 然后将更新的数据批量插入到暂存表中。
在那时,废弃先前的表,并使用一些DDL语句将暂存表作为真实表,放置适当的索引、FK等。
这将是处理此数量级记录的最快方法。其他任何方法都可能需要至少几天时间来处理所有内容。