我有一個查詢,這需要我的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秒)。
更新
我最終把結果放在一個臨時表。然後做過濾。這似乎很快。
只有在您的選擇查詢中引用CTE時纔會調用CTE。在你的where子句中設置一個低的RowNum限制它,所以它只需要做select直到它匹配,增加它意味着它將需要做更多的工作 – dbajtr
似乎使用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
CTE在結果集上執行,所以集合越大,查詢越慢。 (因此 - 名稱「窗口功能」)。有許多可能的解決方法,但它們取決於實際的查詢。然而,我會嘗試的第一件事是將包含rownumber的結果選入臨時表(不是表變量),並將其用作基礎而不是CTE。如上所述 - 還有其他技術可以嘗試使用選擇TOP和NOT IN,或者使用聯合和自聯接來最小化查詢並優化索引。但是,如果沒有實際查詢,很難建議 –