TSQL - 如何防止此查询中的优化

时间:2013-08-20 08:45:37

标签: sql-server optimization sql-server-2008-r2

我的查询类似于:

update x
     set x.y = (
        select sum(x2.y)
        from mytable x2
        where x2.y < x.y
     )
from mytable x

关键是,我正在迭代行并根据子字母更新字段正在更改

我所看到的是,在发生任何更新之前,每行都会执行子查询,因此每行的更改值都 被拾取。

如何强制为更新的每一行重新评估子查询?

是否有合适的表格提示或其他内容?

顺便说一句,我做下面的事情并且它确实有效,但是由于修改我的查询(为了逻辑目的,不尝试解决这个问题)这个技巧不再有用:(

declare @temp int
update x
     set @temp = (
        select sum(x2.y)
        from mytable x2
        where x2.y < x.y
     ),
     x.y = @temp
from mytable x

我并不特别关心性能,这是一个运行几行的后台任务

1 个答案:

答案 0 :(得分:0)

看起来任务不正确或应该适用其他规则。

让我们看一下例子。假设你有值 4,1,2,3,1,2

Sql将根据原始值更新行。即在单个更新语句期间,新计算的值不与原始值混合:

--  only original values used
4 -> 9     (1+2+3+1+2)
1 -> null
2 -> 2     (1+1)
3 -> 6     (1+2+1+2)
1 -> null
2 -> 2     (1+1)

根据您的请求,您希望每行的更新将计算新计算的值。 (注意,SQL不保证处理行的顺序。) 让我们通过从上到下处理行来进行计算:

--  from top
4 -> 9    (1+2+3+1+2)
1 -> null
2 -> 1    (1)
3 -> 4    (1+1+2)
1 -> null
2 -> 1    (1)

以其他顺序执行相同操作 - 从下到上:

--  from bottom
4 -> 3    (2+1)
1 -> null 
2 -> 1    (1)
3 -> 5    (2+2+1)
1 -> null
2 -> 2    (1+1)

如何看待预期结果不一致。为了使其正确,您需要更正计算规则 - 例如,定义要处理的行的强序列(日期,ID,...) 另外,如果您想进行一些递归处理,请查看 common_table_expression

http://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx