Sql-Server

為什麼要為循環選擇頂級查詢和臨時表而不是游標?

  • January 18, 2018

當談到在 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 年開始)可能會回答您的問題,因為他在以下位置進行了幾次比較測試:

簡而言之,他發現正確的游標執行速度明顯快於幾個循環結構。

閱讀他的比較應該可以幫助您對游標感到滿意。

但僅在需要它們時。

引用自:https://dba.stackexchange.com/questions/84365