SQL:表中的持久计算字段有时在查询执行期间不使用

时间:2011-02-23 12:24:12

标签: sql-server sql-server-2008

  

可能重复:
  Why does the Execution Plan include a user-defined function call for a computed column that is persisted?

在SQL Server 2008中,我在长时间运行的查询中运行SQL分析器,并且可以看到正在重复计算持久计算列。我之前已经注意到了这一点,并且有传闻说,这似乎发生在更复杂的查询和/或至少有几千行的表中。

这次重新计算肯定是长时间执行的原因,因为如果我从返回的结果中注释掉一个列(该字段是通过对Xml字段运行XPath来计算的话),它会大大加快。

编辑:违规SQL具有以下结构:

DECLARE @OrderBy nvarchar(50);

SELECT
    A.[Id],     
    CASE
          WHEN @OrderBy = 'Col1' THEN A.[ComputedCol1]
          WHEN @OrderBy = 'Col2' THEN C.[ComputedCol2]
          ELSE C.[ComputedCol3]
    END AS [Order]
FROM
    [Stuff] AS A
INNER JOIN
    [StuffCode] AS SC
ON
    A.[Code] = SC.[Code]

所有列都是nvarchar(50),但ComputedCol3是nvarchar(250)。

1 个答案:

答案 0 :(得分:0)

查询优化器总是尝试选择最便宜的计划,但它可能无法做出正确的选择。通过持久化列,您将它放在主表(在聚簇索引或堆中)中,但为了提取这些值,仍然需要正常的数据访问路径。

这意味着引擎可以选择其他索引而不是主表来满足查询,并且如果它认为这样做,那么它可以选择重新计算计算列,结合其选择的I / O访问模式将花费更少。通常,相当多的CPU比一点I / O便宜,但是没有对表达式的成本进行内部分析,所以如果你的列调用昂贵的UDF,它可能会做出错误的决定。

在列上添加索引可能会有所不同。请注意,您不必使列保持不变以在其上放置索引。如果在制作索引后,引擎仍然出错,请检查是否收集了正确的统计信息,并经常更新表中的所有索引。

如果您发布了表的结构(只是重要的列)和任何索引的定义,以及执行计划在事情变得糟糕时的概念,它将帮助我们。

要考虑的一件事是,在某些情况下重新计算列实际上可能更好,所以确保在执行此操作之前强制引擎获取它是非常正确的。