SQL 高效分頁(百萬條資料)ROW_NUMBER() OVER (ORDER BY id) | 分頁
阿新 • • 發佈:2019-01-28
第一種方法:效率最高
SELECT TOP 頁大小 * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1 ) as A WHERE RowNumber > 頁大小*(當前頁-1) --註解:首先利用Row_number()為table1表的每一行新增一個行號,給行號這一列取名'RowNumber' 在over()方法中將'RowNumber'做了升序排列 --然後將'RowNumber'列 與table1表的所有列 形成一個表A --重點在where條件。假如當前頁(currentPage)是第2頁,每頁顯示10個數據(pageSzie)。那麼第一頁的資料就是第11-20條 --所以為了顯示第二頁的資料,即顯示第11-20條資料,那麼就讓RowNumber大於 10*(2-1) 即:頁大小*(當前頁-1)
將上面的方法寫成儲存過程 (表名Location)
if(exists(select* from sys.procedures where name='p_location_paging'))--如果p_location_paging這個儲存過程存在 drop proc p_location_paging --那麼就刪除這個儲存過程 go create proc p_location_paging(@pageSize int, @currentPage int)--建立儲存過程,定義兩個變數'每頁顯示的條數'和'當前頁' as select top (@pageSize) * from ( select ROW_NUMBER() over(order by locid) as rowid ,* from location )as A where rowid> (@pageSize)*((@currentPage)-1)
簡單的說row_number()從1開始,為每一條分組記錄返回一個數字
第二種方法:效率次之
SELECT TOP 頁大小 * --如果每頁顯示10條資料,那麼這裡就是查詢10條資料 FROM table1 WHERE id > --假如當前頁為第三頁,那麼就需要查詢21-30條資料,即:id>20 ( SELECT ISNULL(MAX(id),0) --查詢子查詢中最大的id FROM ( SELECT TOP 頁大小*(當前頁-1) id FROM table1 ORDER BY id --因為當前頁是第三頁,每頁顯示十條資料。那麼我將: 頁大小*(當前頁-1),就是獲取到了在"當前頁""前面"的20條資料。所以上面用max(id)查詢最大的id,取到這個20,那麼前面的where 條件的id>20 即取到了第三頁的資料,即取21-30條資料 ) as A ) ORDER BY id
將上面的方法寫成儲存過程:表名Location
if(exists(select * from sys.procedures where name='p_location_paging'))
drop proc p_location_paging
go
create proc p_location_paging(@pageSize int ,@currentPage int)
as
select top (@pageSize) * from location
where locId>(select ISNULL(MAX(locId),0)
from (select top ((@pageSize)*(@currentPage-1))locid from location order by locId) as a
)
order by locId
第三種方法:效果最差
SELECT TOP 頁大小 *
FROM table1
WHERE id NOT IN --where條件語句限定要查詢的資料不是子查詢裡面包含的資料。即查詢"子查詢"後面的10條資料。即當前頁的資料
(
--如果當前頁是第二頁,每頁顯示10條資料,那麼這裡就是獲取當前頁前面的所有資料。
SELECT TOP 頁大小*(當前頁-1) id FROM table1 ORDER BY id
)
ORDER BY id
在知道總的資料量,及每頁顯示多少條資料後。計算總的頁數
<1> 即便資料總的條數為0。也顯示一頁; 即:總頁數=1
int dataCount; //資料的總的條數
int pageSize; //每頁顯示多少條資料
int pageCount; //總的頁數
pageCount = dataCount % pageSize == 0 ? ((dataCount - pageSize >= 0 ? (dataCount / pageSize) : 1)) : dataCount / pageSize + 1;
//上面這句話分解一下就是:
if(dataCount%pageSize==0)
{
if(dataCount-pageSize>=0) //即if(dataCount>pageSize)
{
pageCount=dataCount/pageSize;
}
else
{
pageCount=1; //假如資料的總條數只有8條資料。而每頁顯示10條資料;也就是說8%10的結果是等於0的。但是既然有8條資料,我也需要用1頁來顯示這8條資料。所有就有這個條件:即:即便dataCount%pageSize==0的時候,在dataCount<pageSize的情況下,總頁數PageCount最少也得有一頁吧!所以這裡就將pageCount設為1了。
}
}
else
{
dataCount=(dataCount/pageSize)+1;
}
<2>如果資料總條數為0。連一頁都不需要顯示;即:總頁數=0
int dataCount; //資料的總的條數
int pageSize; //每頁顯示多少條資料
int pageCount; //總的頁數
pageCount = dataCount % pageSize == 0 ? ((dataCount - pageSize >= 0 ? (dataCount / pageSize) : (dataCount==0?0:1))) : dataCount / pageSize + 1;
//上面這句話分解一下就是:
if(dataCount%pageSize==0)
{
if(dataCount-pageSize>=0) //即if(dataCount>pageSize)
{
pageCount=dataCount/pageSize;
}
if(dataCount=0)
{
pageCount=0; //相比上面那個計算總頁數,這裡多了這麼一條判斷。如果連一條資料都沒有的情形下,我連一頁都不需要顯示,即:讓總頁數為0,
}
else
{
pageCount=1; //假如資料的總條數只有8條資料。而每頁顯示10條資料;也就是說8%10的結果是等於0的。但是既然有8條資料,我也需要用1頁來顯示這8條資料。所有就有這個條件:即:即便dataCount%pageSize==0的時候,在dataCount<pageSize的情況下,總頁數PageCount最少也得有一頁吧!所以這裡就將pageCount設為1了。
}
}
else
{
dataCount=(dataCount/pageSize)+1;
}