在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)。
答案 0 :(得分:0)
查询优化器总是尝试选择最便宜的计划,但它可能无法做出正确的选择。通过持久化列,您将它放在主表(在聚簇索引或堆中)中,但为了提取这些值,仍然需要正常的数据访问路径。
这意味着引擎可以选择其他索引而不是主表来满足查询,并且如果它认为这样做,那么它可以选择重新计算计算列,结合其选择的I / O访问模式将花费更少。通常,相当多的CPU比一点I / O便宜,但是没有对表达式的成本进行内部分析,所以如果你的列调用昂贵的UDF,它可能会做出错误的决定。
在列上添加索引可能会有所不同。请注意,您不必使列保持不变以在其上放置索引。如果在制作索引后,引擎仍然出错,请检查是否收集了正确的统计信息,并经常更新表中的所有索引。
如果您发布了表的结构(只是重要的列)和任何索引的定义,以及执行计划在事情变得糟糕时的概念,它将帮助我们。
要考虑的一件事是,在某些情况下重新计算列实际上可能更好,所以确保在执行此操作之前强制引擎获取它是非常正确的。