Sql-Server
為什麼要為循環選擇頂級查詢和臨時表而不是游標?
當談到在 T-SQL 中循環大量數據時,我在 Internet 上看到的大多數範例都使用這樣的模式:
declare @someVariable int declare @remainingRows int select someColumn from someTables into #someTempTable select @remainingRows = count(*) from #someTempTable while @remainingRows > 0 begin select top 1 @someVariable = someColumn from #someTempTable -- Do stuff delete top 1 from #someTempTable select @remainingRows = count(*) from #someTempTable end
這似乎比使用這樣的游標範例更常見:
declare @someVariable int select someColumn from someTables into #someTempTable declare @someCursor cursor for select someColumn from #someTempTable open @someCursor fetch next @someVariable from @someCursor while @@fetch_status = 0 begin -- Do stuff fetch next @someVariable from @someCursor end close @someCursor
我有時會聽到提到性能原因,但對我來說這是違反直覺的;迭代一組數據的只進只讀游標不會比不斷查詢和更新臨時表更有效嗎?我知道,如果它是一個游標迭代一個帶有錯誤選項的表,該表可能會被鎖定以進行更新,但是一個非共享臨時表上的游標不會有這個問題,不是嗎?
獎金問題;如果游標沒問題,使用快照隔離的正常查詢上的游標是否安全,這樣我就可以避免手動創建臨時表的煩惱,即:
DECLARE @someCursor CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR SELECT something FROM tables
不,循環不一定比游標快,儘管有些人更喜歡它們。我自己曾經經歷過循環寫作階段。游標也有多種形式,因此選擇正確類型的游標是一個重要的細節。
Aaron Bertrand(從 2012 年開始)可能會回答您的問題,因為他在以下位置進行了幾次比較測試:
簡而言之,他發現正確的游標執行速度明顯快於幾個循環結構。
閱讀他的比較應該可以幫助您對游標感到滿意。
但僅在需要它們時。