2011-03-24 68 views
5

使用SQL 2005年/ 2008年什麼是用於sql循環的遊標的替代方法?

我必須使用前向遊標,但我不想遭受糟糕的表現。有沒有更快的方式,我可以不使用遊標循環?

+2

這完全取決於你正在嘗試做什麼!也許給我們一個提示,所以我們可以給你一個對你的情況有意義的答案? – Oded 2011-03-24 21:19:18

+0

它不是我,我的經理不希望我使用遊標。最終我正在尋找取代光標循環..! – goofyui 2011-03-24 21:23:36

+3

我正在談論您認爲需要使用遊標的特定任務。解釋這是什麼,並給出一個有用的答案。 – Oded 2011-03-24 21:47:56

回答

4

你可以做一個WHILE循環,但是你應該尋求實現更基於集合的操作,如SQL東西都反覆受到性能問題。

http://msdn.microsoft.com/en-us/library/ms178642.aspx

+0

循環實際上是光標的一部分? – goofyui 2011-03-24 21:24:45

+0

我認爲@Dustin在說如果你可以使用基於集合的操作來做到這一點,循環可能是完全沒有必要的。 – DaveE 2011-03-24 21:36:42

+0

和@DavE,你們都可能是對的。你究竟想要通過Set Operators來解釋什麼?我相信遞歸查詢可以做到這一點..! – goofyui 2011-03-24 21:41:21

1

這是不準確的說法 「遊標影響SQL的性能」。他們肯定有一種傾向,但很多都與人們如何使用它們有關。

第一種選擇是嘗試找到問題的基於集合的方法。

如果在邏輯上沒有基於集合的方法,並且對遊標的查詢正在碰到實數(非Temp)表,則使用STATIC關鍵字將SELECT語句的結果放入臨時表中,因此在遍歷結果時,不會鎖定查詢的基表。如果您需要對處理結果集時可能會消失的記錄敏感,那麼使用STATIC將無濟於事,但如果您正在考慮轉換爲臨時表的WHILE循環,這是一個有爭議的問題(因爲它也不知道更改到底層數據)。

+1

http://www.sqlbook.com/SQL/Avoiding-using-SQL-Cursors-20.aspx - 我發現了一篇關於while循環替換遊標的文章..!正如你/ @戴夫提到的那樣。再次,在這裏,我們正在創建一個臨時表..! – goofyui 2011-03-24 21:51:20

+0

我不一定說要創建臨時表。我在說使用STATIC關鍵字會自動將Cursor查詢的結果存儲在臨時表中,因此不會鎖定查詢中的任何表。值得探索的是,只需在代碼中添加一個單詞「STATIC」,就可以在重新設計代碼以獲得WHILE循環之前獲得所需的性能增益。 – 2011-03-26 18:25:44

1

根據您的需要,您可以使用計數表。

傑夫MODEN對符合表Here

1

公用表表達式將是一個不錯的選擇,因爲@Neil建議的優秀文章。下面是AdventureWorks中的一個例子:

WITH cte_PO AS 
(
SELECT [LineTotal] 
    ,[ModifiedDate] 
FROM [AdventureWorks].[Purchasing].[PurchaseOrderDetail] 
), 
minmax AS 
(
    SELECT MIN([LineTotal]) as DayMin 
     ,MAX([LineTotal]) as DayMax 
     ,[ModifiedDate] 
    FROM cte_PO 
    GROUP BY [ModifiedDate] 
) 
SELECT * FROM minmax ORDER BY ModifiedDate 

這裏是什麼返回前幾行:

DayMin  DayMax  ModifiedDate 
135.36  8847.30 2001-05-24 00:00:00.000 
129.8115 25334.925 2001-06-07 00:00:00.000 
1

不要使用遊標,而不是尋找一個基於集合的解決方案。如果您找不到基於集合的解決方案...仍然不使用光標!發佈您想要實現的細節,有人可以爲您找到基於集合的解決方案。

2

我必須使用正向遊標,但我不想遭受糟糕的性能。有沒有更快的方式,我可以不使用遊標循環?

這取決於你的光標做什麼。

幾乎一切都可以用在這種情況下,環路查詢計劃內進行基於集合的操作被重寫,因爲它們不涉及上下文切換速度更快。

但是,有些事情SQL Server只是不擅長,如計算累計值或加入日期範圍。

這些類型的查詢可以使用CURSOR進行得更快:

但同樣,這是一個相當罕見的例外,通常基於集合的方式更好地執行。

如果您發佈您的查詢,我們可以優化它,並擺脫CURSOR

0

可能有些場景可以使用Tally tables。它可能是循環和cusrors的一個很好的選擇,但記住它不能適用於任何情況。一個很好的解釋案例可以發現here