不同數據庫的分頁查詢


1、mysql分頁查詢

方式1:

select * from table order by id limit m, n; 

 

  該語句的意思為,查詢m+n條記錄,去掉前m條,返回后n條記錄。無疑該查詢能夠實現分頁功能,但是如果m的值越大,查詢的性能會越低(越后面的頁數,查詢性能越低),因為MySQL同樣需要掃描過m+n條記錄。

 

方式2:

select * from table where id > #max_id# order by id limit n;

 

  該查詢每次會返回n條記錄,卻無需像方式1掃描過m條記錄,在大數據量的分頁情況下,性能可以明顯好於方式1,但該分頁查詢必須要每次查詢時拿到上一次查 詢(上一頁)的一個最大id(或最小id)。該查詢的問題就在於,我們有時沒有辦法拿到上一次查詢(上一頁)的最大id(或最小id),比如當前在第3 頁,需要查詢第5頁的數據,該查詢方法便愛莫能助了。

 

 方式3:

  為了避免能夠實現方式2不能實現的查詢,就同樣需要使用到limit m, n子句,為了性能,就需要將m的值盡力的小,比如當前在第3頁,需要查詢第5頁,每頁10條數據,當前第3頁的最大id為#max_id#:

 select * from table where id > #max_id# order by id limit 20, 10;

 

  其實該查詢方式是部分解決了方式2的問題,但如果當前在第2頁,需要查詢第100頁或1000頁,性能仍然會較差。

 

方式4:

 select * from table as a inner join (select id from table order by id limit m, n) as b on a.id = b.id order by a.id;

 

  該查詢同方式1一樣,m的值可能很大,但由於內部的子查詢只掃描了字段id,而不是整張表,所以性能要強於方式1查詢,並且該查詢能夠解決方式2和方式3不能解決的問題。

 

 方式5:

 select * from table where id > (select id from table order by id limit m, 1) limit n;

 

  該查詢方式同方式4,同樣通過子查詢掃描字段id,效果同方式4。至於性能的話,方式5的性能會略好於方式4,因為方式5不需要在進行表的關聯,而是一個簡單的比較。

 


 2、sql server分頁查詢

 

方式1:

    --pageSize 每頁顯示的數量
    --pageIndex 起始索引  

select top pageSize * 
from (select row_number() over(order by ID asc) as rownumber,*
from student) temp_row
where rownumber>((pageIndex-1)*pageSize);

方式1-1:按照條件進行分組排序

    --pageSize 每頁顯示的數量
    --pageIndex 起始索引  

select top pageSize * 
from (select row_number() over(partition by CID order by ID asc) as rownumber,*
from student) temp_row
where CID=32 and rownumber>((pageIndex-1)*pageSize);

 

 

方式2:

 

  假設頁數是10,現在要拿出第5頁的內容,查詢語句如下:
  --10代表分頁的大小

復制代碼
select top 10 *
from test
where id not in
(
 --40是這么計算出來的:10*(5-1)
 select top 40 id from test order by id
)
order by id
復制代碼

 

  原理:需要拿出數據庫的第5頁,就是40-50條記錄。首先拿出數據庫中的前40條記錄的id值,然后再拿出剩余部分的前10條元素

 

 方式3:

  還是以上面的結果為例,采用另外的一種方法
  --數據的意思和上面提及的一樣

復制代碼
select top 10 *
from test
where id >
(
 select isnull(max(id),0)
 from 
  (
   select top 40 id from test order by id
  ) A
)
order by id
復制代碼

 

   原理:先查詢前40條記錄,然后獲得其最id值,如果id值為null的,那么就返回0,然后查詢id值大於前40條記錄的最大id值的記錄。這個查詢有一個條件,就是id必須是int類型的。

 

 方式3:

復制代碼
select top 10 *
from 
(
 select row_number() over(order by id) as rownumber,* from test
) A
where rownumber > 40
復制代碼

 

   原理:先把表中的所有數據都按照一個rowNumber進行排序,然后查詢rownuber大於40的前十條記錄
  這種方法和oracle中的一種分頁方式類似,不過只支持2005版本以上的

 

 方式4:

   存儲過程查詢
   創建存儲過程

復制代碼
alter procedure pageDemo
@pageSize int,
@page int
AS
declare @temp int
set @temp=@pageSize*(@page - 1)
begin
 select top (select @pageSize) * from test where id not in (select top (select @temp) id from test) order by id
end
執行存儲過程
exec 10,5
復制代碼

 

 

 


3、oracle分頁查詢

方式1:

  根據ROWID來分

select * from t_xiaoxi where rowid in(select rid from (select rownum rn,rid from(select rowid rid,cid from
t_xiaoxi  order by cid desc) where rownum<10000) where rn>9980) order by cid desc;

 

  執行時間0.03秒

 

方式2:

  按分析函數來分

select * from (select t.*,row_number() over(order by cid desc) rk from t_xiaoxi t) where rk<10000 and rk>9980;

 

  執行時間1.01秒

 

方式3:

  按ROWNUM來分

select * from(select t.*,rownum rn from(select * from t_xiaoxi order by cid desc) t where rownum<10000) where

 

  rn>9980;執行時間0.1秒

  其中t_xiaoxi為表名稱,cid為表的關鍵字段,取按CID降序排序后的第9981-9999條記錄,t_xiaoxi表有70000多條記錄
  個人感覺1的效率最好,3次之,2最差


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM