在這種情況下,CTE(微型優化,我知道...)中必需的SELECT TOP。SQL - 使用CTE並有效地選擇特定row_number處的行()
DECLARE @pageSize INT, @currentPage INT, @top INT
SET @pageSize = 10
SET @currentPage = 150
SET @top = @pageSize * @currentPage + @pageSize
WITH t AS
(
SELECT TOP(***@top***) ID, name
ROW_NUMBER() OVER (ORDER BY ID) AS _row,
FROM dbo.User
)
SELECT TOP(@pageSize) *
FROM t
WHERE t._row > (@[email protected])
ORDER BY t.ID
以上以特定順序從行號列中返回10個(@pageSize)行的起始數字(@ top- @ pageSize)。 CTE聲明是否知道在CTE之外的「SELECT TOP」和WHERE子句(也在CTE之外)即將到來,因此CTE從不以特定順序返回比所需更多的行?
基本上只是談論ROW_NUMBER函數,它不會計算沒有返回的行的行號(如果我有數百萬行......),並且如果我要選擇CTE中的前100個,row_number仍然會被計算爲所選表格中的所有百萬行?
我已經嘗試過並且沒有在CTE語句中的「SELECT TOP(@top)」,在10.000次運行的循環中沒有看到時間使用的任何區別。儘管如此,我目前在桌上只有38000排。
編輯: 所以結果:
WITH t AS
(
**DO A TOP() WITH AN ORDER BY IN THE CTE**
SELECT TOP(@top) ID, name
ROW_NUMBER() OVER (ORDER BY ID) AS _row,
FROM dbo.User
ORDER BY ID
)
SELECT TOP(@pageSize) *
**SELECTING TOP N FROM THE CTE, WHERE ROW-NUMBER IS ... DUE TO THE CTE IS IN ORDER ALREADY**
FROM t
WHERE t._row > (@[email protected])
這很可能是更有效的,如果我命令他們「倒退」,選擇CTE的「底部@pageSize」,這將離開了,而─條款......但如果實際速度更快,則需要進行一些測試......
當然,它需要在CTE內部使用頂層命令,否則您將獲得行的存儲順序,並基於您根據順序返回10的順序...所以,謝謝指出這一點。但是,如果該表有1億行,如何優化CTE?對我而言,當我讀取CTE時,它會選擇ID,名稱並計算表中每行1億行的行號,即使查詢的「最後部分」只選擇了行,這也會慢一點從15.000到15.010 ...? – 2014-12-06 16:30:51
@ØyvindBerg。 。 。您*不會獲得排除'order by'命令時存儲行的順序。你會得到一個任意的順序,這通常可能與訪問方法有關,但是沒有,沒有,也沒有保證。 – 2014-12-06 17:24:32
我並不是指第一個INSERTED行始終是第一個SELECTED,當省略「order by」時...但是按照順序,它們被「存儲」,其中存儲順序(「任意」順序)由諸如索引,等等......但我想我已經得到了這個,編輯了我的問題並且標記了你的回答。 「由於row_number()在頂部之前完成」... – 2014-12-06 19:14:15