2013-08-20 39 views
2

我有類似的查詢:TSQL - 如何防止優化這個查詢

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 

我不是特別在意性能,這是在幾排

+0

我看到你發佈了一個工程,你也可以顯示你正在嘗試工作的一個? –

+4

這是不可能的。這將是一個錯誤,如果是的話。 SQL Server會爲[萬聖節保護](http://blogs.msdn.com/b/craigfr/archive/2008/02/27/halloween-protection.aspx)的計劃添加適當的操作符,以防止您想要的行爲。 –

+0

@DennisJaheruddin什麼?最上面的查詢就是我想要做的工作。第二個以前在不同情況下工作 –

回答

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