更新包含许多列的表中的行

时间:2009-08-19 20:33:02

标签: sql sql-server performance

我有一个表(实际上有几个)包含很多列(可能是100多个)。如果只更改了几列,那么在更新表中的行时性能最佳。

  1. 动态构建UPDATE语句,仅更新已更改的列。
  2. 构建一个参数化的UPDATE语句,其中包含所有列,包括那些未更改的列。
  3. 创建一个将所有值作为参数并更新行的过程。
  4. 我正在使用SQL Server。表中没有BLOBS。

    谢谢/ M

3 个答案:

答案 0 :(得分:4)

我想说从性能角度来看,数字2和3是等价的。如果您使用PK来确定要更新的行并且它是一个聚簇键,那么我不担心将列更新为自身。第一种情况的问题是你将导致“过程缓存膨胀”,你有许多类似的计划都占用你的计划缓存,因为它们是更新的稍微不同的迭代。

如果您计划进行大量更新,我可能会建议更新所有列,因为它可能会导致FK查找等。

谢谢, 埃里克

答案 1 :(得分:1)

选项2和3需要在更新时将更多数据传输到服务器 - 因此只有数据的通信开销更大。

每行是否有不同的更新列集,或者是否为任何给定的运行更新了相同的列集(但列表可能因运行而异)?

在后一种情况下(在给定运行中更新的同一组列),选项1可能表现更好;该声明将准备一次并多次使用,每次更新都会将最少的数据传输到服务器。

在前一种情况下,我会查看是否有一个相对较小的列子集被更改(比如10列在不同的行中更改,即使任何一行只更改为其中的3个) )。在那种情况下,我可能会对10列进行参数化,接受传输7-9列值的相对较小的开销,这些值没有因为单个预准备语句的方便而改变。如果更新列的集合遍布地图(例如,在整个操作中更新了100列中的50多列),那么处理整个操作可能更简单。

在某种程度上,这取决于您的宿主语言(客户端API)如何轻松地处理各种可能的参数化更新方法。

答案 2 :(得分:0)

我投票支持p.1与p.2混合,即动态构建一个仅更新已更改列的参数化UPDATE语句。这适用于您的读/写速率处于“读取”状态并且您没有经常更新的情况,因此我们可以安全地交换查询计划缓存以获得(物理)更新性能。