1

我有一個查詢,這需要我的SQL 2008數據庫1.4秒。然後我試着用這個模板做子查詢:MSSQL中慢速CTE子查詢

;with __myResults as (
    ... my initial query ... already has a column: 
    row_number() over (ORDER BY ...) as RowNum 
) 
select * from __myResults where RowNum between X and Y 

如果我將X和Y設置爲低數字,它表現良好。大約需要0.3秒。 如果我將X和Y設置爲較高的數字,則它會比初始查詢更差。它在運行時不斷增加,如果我增加X和Y.

這是怎麼回事?

我試圖做的是比較執行計劃,但它們是相同的(只是在看「成本:N%」)

如何調試呢?我在哪裏可以看到問題出在哪裏?

我也試過如下:

where RowNum > highNumber 

爲快!而

where RowNum > highNumber and RowNum < highNumber + 10 

很慢。最後:

where RowNum < highNumber 

很慢(6秒)。

更新

我最終把結果放在一個臨時表。然後做過濾。這似乎很快。

+0

只有在您的選擇查詢中引用CTE時纔會調用CTE。在你的where子句中設置一個低的RowNum限制它,所以它只需要做select直到它匹配,增加它意味着它將需要做更多的工作 – dbajtr

+0

似乎使用row_number的方法被用來將結果集分割成幾部分?你有沒有考慮過使用[offset fetch next](https://stackoverflow.com/questions/37184267/in-sql-server-2014-order-by-clause-with-offset-fetch-next-returns-weird-results) ?它僅在sql server 2012之後纔可用。 – LukStorms

+0

CTE在結果集上執行,所以集合越大,查詢越慢。 (因此 - 名稱「窗口功能」)。有許多可能的解決方法,但它們取決於實際的查詢。然而,我會嘗試的第一件事是將包含rownumber的結果選入臨時表(不是表變量),並將其用作基礎而不是CTE。如上所述 - 還有其他技術可以嘗試使用選擇TOP和NOT IN,或者使用聯合和自聯接來最小化查詢並優化索引。但是,如果沒有實際查詢,很難建議 –

回答

0

爲什麼不使用FETCH/OFFSET

select * 
from __myResults 
order by ?? 
offset X - 1 
fetch next (X - Y) rows only; 

您需要調整參數XY

+0

感謝您的反饋。我只是意識到,我們必須支持MS SQL 2008 :( – ims1234

+0

我只是測試它,現在所需的最大時間,不比最初的查詢慢!謝謝。所以這可能是可以理解的,整個查詢必須掃描即使正在使用偏移量 – ims1234

+0

@ ims1234 ...您是否在'order by'列中有索引? –