分頁查詢在web開發中是最常見的一種技術,最近在通過查資料,有一點自己的心得
一、mysql中的分頁查詢
注:m=(pagenum-1)*pagesize;n= pagesize;
pagenum是要查詢的頁碼,pagesize是每次查詢的資料量,
方法一:
select * from table order by id limit m, n;
該語句的意思為,查詢m+n條記錄,去掉前m條,返回後n條記錄。無疑該查詢能夠實現分頁功能,但是如果m的值越大,查詢的效能會越低(越後面的頁數,查詢效能越低),因為mysql同樣需要掃瞄過m+n條記錄。
方法二:
select * from table where id > #max_id# order by id limit n;
方法三:
為了避免能夠實現方式二不能實現的查詢,就同樣需要使用到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頁,需要查詢第100頁或1000頁,效能仍然會較差。
方法四:
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;
該查詢同方式一 一樣,m的值可能很大,但由於內部的子查詢只掃瞄了字段id,而不是整張表,所以效能要強於方式一查詢,並且該查詢能夠解決方式二和方式三不能解決的問題。
方式五:
select * from table where id > (select id from table order by id limit m, 1) limit n;
該查詢方式同方式四,同樣通過子查詢掃瞄欄位id,效果同方式四。至於效能的話,方式五的效能會略好於方式四,因為方式5不需要在進行表的關聯,而是乙個簡單的比較。
二、sql server分頁查詢
方法一:
適用於 sql server 2000/2005
select top 頁大小 *from table1
where id not in
(select top 頁大小*(頁數-1) id from table1 order by id
)order by id
方法二:
適用於 sql server 2000/2005
--順序寫法:select top 頁大小 *
from table1
where id >=
( select isnull(max(id),0)
from
( select top 頁大小*(頁數-1)+1 id from table1 order by id
) a) order by id
--降序寫法:
select top 頁大小 *
from table1
where id <=
( select isnull(min(id),0)
from
( select top 頁大小*(頁數-1)+1 id from table1 order by id desc
) a) order by id desc
方法三:
適用於 sql server 2005
selecttop 頁大小 *
from
(select row_number() over (order
by id) as rownumber,*
from table1
) awhere rownumber > 頁大小*(頁數-
1)
說明,頁大小:每頁的行數;頁數:第幾頁。使用時,請把「頁大小」和「頁大小*(頁數-1)」替換成數字。
其它的方案:如果沒有主鍵,可以用臨時表,也可以用方案三做,但是效率會低。
建議優化的時候,加上主鍵和索引,查詢效率會提高。
通過sql 查詢分析器,顯示比較:我的結論是:
分頁方案二:(利用id大於多少和select top分頁)效率最高,需要拼接sql語句
分頁方案一:(利用not in和select top分頁) 效率次之,需要拼接sql語句
分頁方案三:(利用sql的游標儲存過程分頁) 效率最差,但是最為通用
三、oracle分頁查詢
方法一:
select * from
( select a.*, rownum rn from
(select * from tab) a
where rownum <= 40 )
where rn >= 21;
這個分頁比下面的執行時間少,效率高。當資料量較大時oracle會自動優化!
方法二:
select * from
(select c.*,rownum rn from tab c) where rn between 21 and 40
對比這兩種寫法,絕大多數的情況下,第乙個查詢的效率比第二個高得多。
這是由於cbo優化模式下,oracle可以將外層的查詢條件推到內層查詢中,以提高內層查詢的執行效率。
對於第乙個查詢語句,第二層的查詢條件where rownum <= 40就可以被oracle推入到內層查詢中,
這樣oracle查詢的結果一旦超過了rownum限制條件,就終止查詢將結果返回了。
而第二個查詢語句,由於查詢條件between 21 and 40是存在於查詢的第三層,而oracle無法將第三層的查詢條件推到最內層
(即使推到最內層也沒有意義,因為最內層查詢不知道rn代表什麼)。】因此,對於第二個查詢語句,
oracle最內層返回給中間層的是所有滿足條件的資料,而中間層返回給最外層的也是所有資料。資料的過濾在最外層完成,
顯然這個效率要比第乙個查詢低得多。
上面分析的查詢不僅僅是針對單錶的簡單查詢,對於最內層查詢是複雜的多表聯合查詢或最內層查詢包含排序的情況一樣有效。
MySQL分頁查詢詳解
mysql資料庫limit分頁 排序 sql語句示例 select from tab limit a,b 解釋 a,從.開始查詢 用的是索引 b,一共顯示多少條記錄數 示例 select from tab limit 0 4 解釋 起點位置為0索引,開始查詢,返回4條資料 即第一條記錄到第4條記錄 ...
Oracle分頁查詢詳解 一
oracle的分頁查詢語句基本上可以按照如下格式進行套用。分頁查詢格式 select from select a.rownum rn from select from table name a where rownum 5000 where rn 4000其中最內層的查詢select from ta...
Oracle分頁查詢詳解 四
下面繼續看查詢的第三種情況,即內部迴圈包含排序的情況 準備工作如下 下面進行測試包含排序操作的分頁查詢。可以簡單的將查詢分為兩種不同情況,第一種排序列就是索引列,這種可以利用索引讀取,第二種排序列沒有索引。第一種情況又可以細分為 完全索引掃瞄和通過索引掃瞄定位到表記錄兩種情況。無論是那種情況,都可以...