代码之家  ›  专栏  ›  技术社区  ›  Mikael Sundberg

更新具有多列的表中的行

  •  2
  • Mikael Sundberg  · 技术社区  · 16 年前

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

    1. 要动态生成UPDATE语句,请仅更新已更改的列。
    2. 生成包含所有列(包括未更改的列)的参数化更新语句。
    3. 创建一个将所有值作为参数并更新行的过程。

    我正在使用SQL Server。桌子上没有斑点。

    谢谢/ M

    3 回复  |  直到 16 年前
        1
  •  1
  •   Jonathan Leffler    16 年前

    选项2和3要求在更新时向服务器传输更多的数据,因此仅对数据有更大的通信开销。

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

    在后一种情况下(在给定的运行中更新了同一组列),选项1的性能可能更好;该语句将准备一次,并多次使用,每次更新至少向服务器传输数据。

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

    在某种程度上,这取决于主机语言(客户机API)使其处理参数化更新的各种可能方法的容易程度。

        2
  •  4
  •   Anon246    16 年前

    从性能的角度来说,2和3是等价的。如果您使用一个pk来确定要更新的行,它是一个聚集键,那么我就不用担心将列更新为它自己了。第一种情况的问题是,您将导致“过程缓存膨胀”,其中有许多类似的计划都占用计划缓存,因为它们与更新的迭代略有不同。

    如果您计划进行大规模更新,我可能会犹豫,建议更新所有列,因为这可能会导致fk查找等。

    谢谢, 埃里克

        3
  •  0
  •   AlexS    16 年前

    我将投票赞成P.1和P.2的混合,即动态构建一个参数化的更新语句,它只更新已更改的列。当您的读/写速率处于“读”端,并且您不太频繁地进行更新时,这将适用于这种情况,因此我们可以安全地交换查询计划缓存以获得(物理)更新性能。