SqlSever分頁查詢,僅掃描一次表

數據庫的分頁查詢通常由兩個查詢組成:數據庫

select count(*) from Goods

函數

select *
from (
    select row_number() over(order by goodsId) as rowid, *
    from Goods
) as a
where rowid >= @pageSize * (@pageIndex - 1) + 1
and rowid <= @pageSize * @pageIndex

第一個查詢,獲取符合條件的記錄總數,用於計算總頁數。第二個查詢獲取指定頁上的記錄。測試

兩個查詢須要執行兩次,也就是作兩次表掃描,這對效率是極大的損失。能不能只作一次表掃描?
row_number()函數在作排名時,確定須要作一次表掃描,而排名完成後,確定是知道有多少條記錄的,若是這個內部值能輸出到外部給調用者使用,那麼兩個查詢就能夠合併爲一個查詢,且僅須要一次表掃描了。
通過研究,row_number()函數並無這個功能,可是同時發現 over()這個窗口函數既能夠配合排名函數使用,也能夠配合聚合函數使用。例如:優化

select count(*) over() as recordCount from Goods

那麼,若是利用窗口函數over(),而後同時搭配row_number()排名函數和count()聚合函數,Sql Server的執行計劃可否在內部自動優化爲僅作一次表掃描?因而查詢改成以下:spa

select *
from (
    select count(*) over() as recordTotalCount,
           row_number() over(order by goodsId) as rowid, 
           *
    from Goods
) as a
where rowid >= @pageSize * (@pageIndex - 1) + 1
and rowid <= @pageSize * @pageIndex    

通過測試,因爲在同一個查詢中,都使用了over()窗口函數,Sql Server在生成執行計劃時,自動優化爲僅進行一次表掃描了code

相關文章
相關標籤/搜索