2008-11-24 102 views
15

我有一個運行超快,約爲一秒,一個SQL查詢不使用變量時,如:爲什麼SQL Server在使用變量時變慢?

WHERE id BETWEEN 5461094 and 5461097 

但是,當我有:

declare @firstId int 
declare @lastId int 

set @firstId = 5461094 
set @lastId = 5461097 

... 
    WHERE id BETWEEN @firstId and @lastId 

...查詢運行非常緩慢,幾分鐘後才完成。爲什麼會發生?我需要使用變量。我可以做任何改進以避免這種性能問題嗎?

回答

10

這是因爲當這些值被硬編碼時,它可以查找它對錶中的數據所具有的the statistics,並找出要運行的最佳查詢。查看每個查詢的執行計劃。它必須在您使用變量時進行掃描。

如果範圍總是很小,您可能可以使用索引提示來提供幫助。

+0

在Oracle中,如果範圍總是很小,那麼一切都會好的。它會根據第一個變量來選擇計劃。如果它總是很小,你總是很好。 IT是在極端情況下襬動的情況。我認爲SS最近添加了一些類似於偷看的東西......也許是'05或'08。 – 2008-11-25 18:36:58

0

索引中的ID(例如主鍵)?如果不是,請嘗試添加一個。

另一件事可能是,在第一個(快速)實例中,查詢執行的方式稍有不同。我見過的最常見的事情是,連接以低效率的順序完成。嘗試重新排序連接,或將一些轉換爲子查詢。如果您發佈更多的查詢,我們可以進一步提供幫助。

3

搞笑的是,這個代碼將是太快太:

DECLARE @sql VARCHAR(8000) 

SET @sql = 'SELECT * FROM table_x WHERE id BETWEEN ' + CAST(@firstId AS VARCHAR) + ' AND ' + CAST(@lastId AS VARCHAR) 

EXEC (@sql) 

(MSSQL 2000)

19

OK,

  1. 你是優化和查詢計劃是車輛。
  2. 我會給你一個查詢,你必須選擇車輛。
  3. 所有在圖書館的圖書上的序列號

我的查詢是去圖書館,讓我所有的3至5

書你會選擇自行車吧,快,便宜,高效和足夠大以攜帶3本書。

新查詢。

轉到圖書館,獲取@x和@y之間的所有書籍。

挑車。

繼續。

這就是發生了什麼事。如果我要求1至Maxvalue之間的書籍,你會選擇自卸車嗎?如果x = 3和y = 5,那就太過分了。 SQL必須在看到數字之前選擇該計劃。

+0

已更新的存儲過程並添加了「選項重新編譯」到最後 – atoms 2015-10-07 10:11:56

1

看起來這個查詢涉及到一個存儲過程,它的執行計劃將在第一次執行proc時被編譯,然後重新用於後續執行。

對於firstid與lastid非常接近的情況,其編譯計劃可能非常糟糕,但是當值相差很遠時,它的確很好。

嘗試啓用存儲過程中的WITH RECOMPILE選項。如果它解決了問題,並且您對每次執行過程(您將獲得性能提升)重新編譯的過程感到滿意,那麼將它留在那裏。如果您對性能仍然不滿意,請考慮重新構建proc,以免它需要重新編譯。

0

事實上,它是回答得很好,我只是在這裏寫一個解決方法,因爲它的工作對我來說:

與SQL創建一個存儲過程

WHERE id BETWEEN @firstId and @lastId 

之後再調用存儲過程參數@firstId和@lastId會加快速度。我仍然不是100%,爲什麼它工作,但它的工作原理。

相關問題