我的目标是最大限度地提高绩效。该方案的基础是:
这很好。但是,如果DataTable中的行已更改,则即使9列中只有1列实际更改了值,也会在数据库中更新该记录的所有列。这意味着不必要的工作,特别是涉及索引时。我不相信SQL Server会优化这种情况吗?
我认为,如果我只能更新任何给定记录实际更改的列,那么我应该会看到明显的性能提升(特别是累计,我将处理数百万行)。
我找到了这篇文章:http://netcode.ru/dotnet/?lang=&katID=30&skatID=253&artID=6635 但是不喜欢在sproc中做多个UPDATE的想法。 如果没有为每个已更改的DataRow创建单独的UPDATE语句,然后以某种方式批量触发它们,我正在寻找其他人的经验/建议。
(请假设我不能使用触发器)
提前致谢
编辑:有什么方法可以让SqlDataAdapter发送特定于每个已更改的DataRow的UPDATE语句(仅更新该行中实际更改的列),而不是提供更新所有列的常规.UpdateCommand?
答案 0 :(得分:2)
是否可以在实现此功能的情况下实现自己的IDataAdapter?
当然,DataAdapter只会触发正确的SqlCommand,它由每个DataRow的RowState决定。 所以,这意味着你必须生成必须为每种情况执行的SQL命令......
但是,我想知道这是否值得付出努力。你会获得多少性能?
我认为 - 如果真的有必要 - 我将禁用所有索引和约束,使用常规SqlDataAdapter进行更新,然后启用索引和约束。
答案 1 :(得分:0)
您可能会尝试创建已更改数据集的XML,将其作为参数传递给sproc并使用sql nodes()函数将xml转换为表格形式。
你永远不应该尝试更新聚集索引。如果你这样做是时候重新考虑你的数据库模式。
答案 2 :(得分:0)
我非常建议您使用存储过程执行此操作。 假设您有1000万条记录需要更新。并且假设每个记录有100个字节(对于10个列,这可能太小,但让我们保守)。这相当于cca 100 MB的数据,必须从数据库(网络流量)传输,存储在内存中,然后以UPDATE或INSERT的形式返回到数据库,这些数据更加冗长,无法传输到数据库。
我希望SP会表现得更好。
再次,您可以将工作划分为更小的SP(从主SP调用),它将仅更新必要的字段,并以此方式获得额外的性能。
禁用索引/约束也是一种选择。
编辑:
您必须考虑的另一件事是可能的不同更新语句数。如果每行10个字段,则任何字段都可以保持不变或更改。因此,如果您构造UPDATE语句以反映这一点,您可能会得到10 ^ 2 = 1024个不同的UPDATE语句,其中任何一个必须由SQL Server解析,执行计划计算和解析语句存储在某个区域中。这样做是有代价的。