網(wǎng)站首頁 編程語言 正文
開發(fā)過程中經(jīng)常遇到分頁的需求,今天在此總結(jié)一下吧。
簡單說來方法有兩種,一種在源上控制,一種在端上控制。源上控制把分頁邏輯放在SQL層;端上控制一次性獲取所有數(shù)據(jù),把分頁邏輯放在UI上(如GridView)。顯然,端上控制開發(fā)難度低,適于小規(guī)模數(shù)據(jù),但數(shù)據(jù)量增大時性能和IO消耗無法接受;源上控制在性能和開發(fā)難度上較為平衡,適應(yīng)大多數(shù)業(yè)務(wù)場景;除此之外,還可以根據(jù)客觀情況(性能要求,源與端的資源占用等)在源和端之間加一層,應(yīng)用特殊算法和技術(shù)進(jìn)行處理。以下主要討論源上,即SQL上的分頁。
分頁的問題其實(shí)就是在滿足條件的一堆有序數(shù)據(jù)中截取當(dāng)前所需要展示的那部分。實(shí)際上各種數(shù)據(jù)庫都考慮到分頁問題而內(nèi)置了一些策略,比如MySql的LIMIT,Oracle的ROWNUM和ROW_NUMBER(),SqlServer的TOP和ROW_NUMBER(),基于此我們可以得到一系列分頁的方法。
1、 基于MySql的LIMIT和Oracle的ROWNUM,可以直接限制返回區(qū)間(以MySql為例,注意使用Oracle的ROWNUM時要應(yīng)用子查詢):
方法一、直接限制返回區(qū)間
SELECT * FROM table WHERE 查詢條件 ORDER BY 排序條件 LIMIT ((頁碼-1)*頁大小),頁大小;
優(yōu)點(diǎn):寫法簡單。
缺點(diǎn):當(dāng)頁碼和頁大小過大時,性能明顯下降。
適用:數(shù)據(jù)量不大。
2、基于LIMIT(MySql)、ROWNUM(Oracle)和TOP(SqlServer),他們可以限制返回的行數(shù),因此可以得到以下兩套通用的方法(以SqlServer為例):
方法二、NOT IN
SELECT TOP 頁大小 * FROM table WHERE 主鍵 NOT IN ( SELECT TOP (頁碼-1)*頁大小 主鍵 FROM table WHERE 查詢條件 ORDER BY 排序條件 ) ORDER BY 排序條件
優(yōu)點(diǎn):通用性強(qiáng)。
缺點(diǎn):當(dāng)數(shù)據(jù)量較大時向后翻頁,NOT IN中的數(shù)據(jù)過大會影響性能。
適用:數(shù)據(jù)量不大。
方法三、MAX
SELECT TOP 頁大小 * FROM table WHERE 查詢條件 AND id > ( SELECT ISNULL(MAX(id),0) FROM ( SELECT TOP ((頁碼-1)*頁大小) id FROM table WHERE 查詢條件 ORDER BY id ) AS tempTable ) ORDER BY id
優(yōu)點(diǎn):速度快,特別是當(dāng)id為主鍵時。
缺點(diǎn):適用面窄,要求排序條件單一且可比較。
適用:簡單排序(特殊情況也可嘗試轉(zhuǎn)換成類似可比較值處理)。
3、基于SqlServer和Oracle的ROW_NUMBER(),可以得到返回?cái)?shù)據(jù)的行號,基于此在限制返回區(qū)間得到如下方法(以SqlServer為例):
方法四、ROW_NUMBER()
SELECT TOP 頁大小 * FROM ( SELECT TOP (頁碼*頁大小) ROW_NUMBER() OVER (ORDER BY 排序條件) AS RowNum, * FROM table WHERE 查詢條件 ) AS tempTable WHERE RowNum BETWEEN (頁碼-1)*頁大小+1 AND 頁碼*頁大小 ORDER BY RowNum
優(yōu)點(diǎn):在數(shù)據(jù)量較大時相比NOT IN有優(yōu)勢。
缺點(diǎn):小數(shù)據(jù)量時不如NOT IN。
適用:大部分分頁查詢需求。
原文鏈接:https://www.cnblogs.com/bbgasj/archive/2012/11/06/2756567.html
相關(guān)推薦
- 2022-07-26 Assertion failed: cond.is_weights() && con
- 2022-08-10 Python多任務(wù)版靜態(tài)Web服務(wù)器實(shí)現(xiàn)示例_python
- 2022-06-01 C語言超詳細(xì)講解棧與隊(duì)列實(shí)現(xiàn)實(shí)例_C 語言
- 2022-11-26 利用Python讀取Excel表內(nèi)容的詳細(xì)過程_python
- 2022-12-24 C++中的模板類繼承和成員訪問問題_C 語言
- 2023-01-20 基于?Dubbo?Admin?動態(tài)調(diào)整服務(wù)超時時間的操作步驟_其它綜合
- 2022-04-18 Python基礎(chǔ)中的的if-else語句詳解_python
- 2024-01-06 RocketMQ重復(fù)消費(fèi)問題
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支