【转载】SQL分页查询总结

开发过程中经常遇到分页的需求,今天在此总结一下吧。
    简单说来方法有两种,一种在源上控制,一种在端上控制。源上控制把分页逻辑放在SQL层;端上控制一次性获取所有数据,把分页逻辑放在UI上(如GridView)。显然,端上控制开发难度低,适于小规模数据,但数据量增大时性能和IO消耗无法接受;源上控制在性能和开发难度上较为平衡,适应大多数业务场景;除此之外,还可以根据客观情况(性能要求,源与端的资源占用等)在源和端之间加一层,应用特殊算法和技术进行处理。以下主要讨论源上,即SQL上的分页。
    分页的问题其实就是在满足条件的一堆有序数据中截取当前所需要展示的那部分。实际上各种数据库都考虑到分页问题而内置了一些策略,比如MySql的LIMIT,Oracle的ROWNUM和ROW_NUMBER(),SqlServer的TOP和ROW_NUMBER(),基于此我们可以得到一系列分页的方法。

1、 基于MySql的LIMIT和Oracle的ROWNUM,可以直接限制返回区间(以MySql为例,注意使用Oracle的ROWNUM时要应用子查询):
方法一、直接限制返回区间

SELECT * FROM table WHERE 查询条件 ORDER BY 排序条件 LIMIT ((页码-1)*页大小),页大小;

优点:写法简单。
缺点:当页码和页大小过大时,性能明显下降。
适用:数据量不大。

2、基于LIMIT(MySql)、ROWNUM(Oracle)和TOP(SqlServer),他们可以限制返回的行数,因此可以得到以下两套通用的方法(以SqlServer为例):
方法二、NOT IN

SELECT TOP 页大小 * FROM table WHERE 主键 NOT IN
(
SELECT TOP (页码-1)*页大小 主键 FROM table WHERE 查询条件 ORDER BY 排序条件
)
ORDER BY 排序条件

优点:通用性强。
缺点:当数据量较大时向后翻页,NOT IN中的数据过大会影响性能。
适用:数据量不大。

方法三、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

优点:速度快,特别是当id为主键时。
缺点:适用面窄,要求排序条件单一且可比较。
适用:简单排序(特殊情况也可尝试转换成类似可比较值处理)。

3、基于SqlServer和Oracle的ROW_NUMBER(),可以得到返回数据的行号,基于此在限制返回区间得到如下方法(以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

优点:在数据量较大时相比NOT IN有优势。
缺点:小数据量时不如NOT IN。
适用:大部分分页查询需求。

以上是自己总结的拙见,性能比较来自网上资料及个人判断,并没有深入实验,不当之处请大家指正。

原文地址:https://www.cnblogs.com/bbgasj/archive/2012/11/06/2756567.html

转载:SQL分页查询总结的更多相关文章

  1. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  2. SQL Server SQL分页查询

    SQL Server SQL分页查询的几种方式 目录 0.    序言 1.    TOP…NOT IN… 2.    ROW_NUMBER() 3.    OFFSET…FETCH 4.    执行 ...

  3. SQL分页查询结果不一致

    今天遇到了SQL分页查询结果不一致的情况,一看代码,原来是没加排序查询!!分页查询最好加排序,且以唯一性高的字段进行排序,如ID,时间等,以保持每页查询结果的准确! PS:又帮别人擦屁股!!

  4. Oracle中的SQL分页查询原理和方法详解

    Oracle中的SQL分页查询原理和方法详解 分析得不错! http://blog.csdn.net/anxpp/article/details/51534006

  5. sql分页查询(2005以后的数据库)和access分页查询

    sql分页查询: select * from ( select ROW_NUMBER() over(order by 排序条件) as rowNumber,* from [表名] where 条件 ) ...

  6. 【原创】SQL分页查询存储过程

    ------------------------------------- -----作者:张欣宇 -----时间:2013-06-28 -----简介:根据参数和条件分页查询 ----------- ...

  7. ABAP Open SQL 分页查询

    分页查询是一个常见需求,特别是在web相关的开发当中. 让人意外的是,google搜索abap paging query,查到的结果似乎都指出需要使用native SQL来实现相关功能:使用百度搜索 ...

  8. SQL分页查询,纯Top方式和row_number()解析函数的使用及区别

    听同事分享几种数据库的分页查询,自己感觉,还是需要整理一下MS SqlSever的分页查询的. Sql Sever 2005之前版本: select top 页大小 * from 表名 where i ...

  9. SQL分页查询总结{转}

    开发过程中经常遇到分页的需求,今天在此总结一下吧.简单说来方法有两种,一种在源上控制,一种在端上控制.源上控制把分页逻辑放在SQL层:端上控制一次性获取所有数据,把分页逻辑放在UI上(如GridVie ...

  10. sql分页查询公式

    分页查询公式: select top PageRow(每页显示的数据行数) from 表名 where 主键  not in(select top PageRow*(当前页数-1) 主键  from ...

随机推荐

  1. <一>从指令角度了解函数堆栈调用过程

    代码 点击查看代码 #include <iostream> using namespace std; int sum(int a,int b){ int temp=0; temp= a + ...

  2. Spring Boot 项目自定义 banner

    前言 我们在启动 Spring Boot 项目时,控制台会打印出 Spring Boot 专属的标语,也称 banner(横幅标语/广告),效果如下: 实际上,上面这个 banner,我们可以自定义, ...

  3. 一个 MySQL 隐式转换的坑,差点把服务器整崩溃了

    我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 本来是一个平静而美好的下午,其 ...

  4. 图学习【参考资料2】-知识补充与node2vec代码注解

    本项目参考: https://aistudio.baidu.com/aistudio/projectdetail/5012408?contributionType=1 *一.正题篇:DeepWalk. ...

  5. 嵌入式-C语言基础:字符串拼接函数strcat

    #include<stdio.h> #include <string.h> //实现字符串拼接 char * mystrcat(char * dest,char * src) ...

  6. vue 过滤器时间格式化

    1.导入了一个moment.js插件,里面封装了格式化时间的方法 ①:插件的链接:https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/mom ...

  7. Linux下安装 SkyWalking 分布式追踪系统

    Linux下安装 SkyWalking 分布式追踪系统 1.SkyWalking简介 1.1 SkyWalking介绍 SkyWalking项目是由华为大牛吴晟开源的个人项目,目前已经加入Apache ...

  8. 24、编写一个函数void replace(char *str1,char *str2,int i,int j),将字符串中str1中的第i个字符开始到j个字符结束的位置替换为str2.

    /* 编写一个函数void replace(char *str1,char *str2,int i,int j),将字符串中str1中的第i个字符开始到j个字符结束的位置替换为str2. */ #in ...

  9. <一>继承的基本意义

    1:继承的本质和原理 2:派生类的构造过程 3:重载,覆盖,隐藏 4:静态绑定和动态绑定 5:多态,vfptr,vftable 6:抽象类的设计原理 7:多重继承以及问题 8:虚基类 vbptr 和v ...

  10. .NET 6 实现滑动验证码(二)、基本数据

    上一节,介绍了滑动验证码的基本情况,也创建了一个.NET 6的工程.本节内容是创建一些基础类. 目录 CaptchaData.cs CaptchaValidateData.cs ImageCaptch ...