高效的SQLSERVER分页查询(推荐)
原文:高效的SQLSERVER分页查询(推荐)

Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID、YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,Sqlserver版本:2008R2

第一种方案、最简单、普通的方法:

SELECT TOP 30 * FROM ARTICLE WHERE ID NOT IN(SELECT TOP 45000 ID FROM ARTICLE ORDER BY YEAR DESC, ID DESC) ORDER BY YEAR DESC,ID DESC  

平均查询100次所需时间:45s

第二种方案:

SELECT * FROM (  SELECT TOP 30 * FROM (SELECT TOP 45030 * FROM ARTICLE ORDER BY YEAR DESC, ID DESC) f ORDER BY f.YEAR ASC, f.ID DESC) s ORDER BY s.YEAR DESC,s.ID DESC  

平均查询100次所需时间:138S

第三种方案:

SELECT * FROM ARTICLE w1,
(SELECT TOP 30 ID FROM (SELECT TOP 50030 ID, YEAR FROM ARTICLE ORDER BY YEAR DESC, ID DESC) w ORDER BY w.YEAR ASC, w.ID ASC
) w2 WHERE w1.ID = w2.ID ORDER BY w1.YEAR DESC, w1.ID DESC

平均查询100次所需时间:21S

第四种方案:

SELECT * FROM ARTICLE w1 WHERE ID in (SELECT top 30 ID FROM (SELECT top 45030 ID, YEAR FROM ARTICLE ORDER BY YEAR DESC, ID DESC) w ORDER BY w.YEAR ASC, w.ID ASC) ORDER BY w1.YEAR DESC, w1.ID DESC

平均查询100次所需时间:20S

第五种方案:

SELECT w2.n, w1.* FROM ARTICLE w1, (  SELECT TOP 50030 row_number() OVER (ORDER BY YEAR DESC, ID DESC) n, ID FROM ARTICLE ) w2 WHERE w1.ID = w2.ID AND w2.n > 50000 ORDER BY w2.n ASC  

平均查询100次所需时间:15S

查询第1000-1030条记录

第一种方案:

SELECT TOP 30 * FROM ARTICLE WHERE ID NOT IN(SELECT TOP 1000 ID FROM ARTICLE ORDER BY YEAR DESC, ID DESC) ORDER BY YEAR DESC,ID DESC  

平均查询100次所需时间:80s

第二种方案:

SELECT * FROM  (   SELECT TOP 30 * FROM (SELECT TOP 1030 * FROM ARTICLE ORDER BY YEAR DESC, ID DESC) f ORDER BY f.YEAR ASC, f.ID DESC) s ORDER BY s.YEAR DESC,s.ID DESC  

平均查询100次所需时间:30S

第三种方案:

SELECT * FROM ARTICLE w1,
(SELECT TOP 30 ID FROM (SELECT TOP 1030 ID, YEAR FROM ARTICLE ORDER BY YEAR DESC, ID DESC) w ORDER BY w.YEAR ASC, w.ID ASC
) w2 WHERE w1.ID = w2.ID ORDER BY w1.YEAR DESC, w1.ID DESC

平均查询100次所需时间:12S

第四种方案:

SELECT * FROM ARTICLE w1 WHERE ID in (SELECT top 30 ID FROM (SELECT top 1030 ID, YEAR FROM ARTICLE ORDER BY YEAR DESC, ID DESC) w ORDER BY w.YEAR ASC, w.ID ASC) ORDER BY w1.YEAR DESC, w1.ID DESC

平均查询100次所需时间:13S

第五种方案:

SELECT w2.n, w1.* FROM ARTICLE w1,(   SELECT TOP 1030 row_number() OVER (ORDER BY YEAR DESC, ID DESC) n, ID FROM ARTICLE) w2 WHERE w1.ID = w2.ID AND w2.n > 1000 ORDER BY w2.n ASC  

平均查询100次所需时间:14S

由此可见在查询页数靠前时,效率3>4>5>2>1,页码靠后时5>4>3>1>2,再根据用户习惯,一般用户的检索只看最前面几页,因此选择3 4 5方案均可,若综合考虑方案5是最好的选择,但是要注意SQL2000不支持row_number()函数,由于时间和条件的限制没有做更深入、范围更广的测试,有兴趣的可以仔细研究下。

以下是根据第四种方案编写的一个分页存储过程:

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sys_Page_v2]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sys_Page_v2]
GOCREATE PROCEDURE [dbo].[sys_Page_v2]
@PCount int output,    --总页数输出
@RCount int output,    --总记录数输出
@sys_Table nvarchar(100),    --查询表名
@sys_Key varchar(50),        --主键
@sys_Fields nvarchar(500),    --查询字段
@sys_Where nvarchar(3000),    --查询条件
@sys_Order nvarchar(100),    --排序字段
@sys_Begin int,        --开始位置
@sys_PageIndex int,        --当前页数
@sys_PageSize int        --页大小
ASSET NOCOUNT ON
SET ANSI_WARNINGS ONIF @sys_PageSize < 0 OR @sys_PageIndex < 0
BEGIN
RETURN
ENDDECLARE @new_where1 NVARCHAR(3000)
DECLARE @new_order1 NVARCHAR(100)
DECLARE @new_order2 NVARCHAR(100)
DECLARE @Sql NVARCHAR(4000)
DECLARE @SqlCount NVARCHAR(4000)DECLARE @Top intif(@sys_Begin <=0)set @sys_Begin=0
elseset @sys_Begin=@sys_Begin-1IF ISNULL(@sys_Where,'') = ''SET @new_where1 = ' '
ELSESET @new_where1 = ' WHERE ' + @sys_WhereIF ISNULL(@sys_Order,'') <> ''
BEGINSET @new_order1 = ' ORDER BY ' + Replace(@sys_Order,'desc','')SET @new_order1 = Replace(@new_order1,'asc','desc')SET @new_order2 = ' ORDER BY ' + @sys_Order
END
ELSE
BEGINSET @new_order1 = ' ORDER BY ID DESC'SET @new_order2 = ' ORDER BY ID ASC'
ENDSET @SqlCount = 'SELECT @RCount=COUNT(1),@PCount=CEILING((COUNT(1)+0.0)/'+ CAST(@sys_PageSize AS NVARCHAR)+') FROM ' + @sys_Table + @new_where1EXEC SP_EXECUTESQL @SqlCount,N'@RCount INT OUTPUT,@PCount INT OUTPUT',@RCount OUTPUT,@PCount OUTPUTIF @sys_PageIndex > CEILING((@RCount+0.0)/@sys_PageSize)    --如果输入的当前页数大于实际总页数,则把实际总页数赋值给当前页数
BEGINSET @sys_PageIndex =  CEILING((@RCount+0.0)/@sys_PageSize)
ENDset @sql = 'select '+ @sys_fields +' from ' + @sys_Table + ' w1 '+ ' where '+ @sys_Key +' in ('+'select top '+ ltrim(str(@sys_PageSize)) +' ' + @sys_Key + ' from '+'('+'select top ' + ltrim(STR(@sys_PageSize * @sys_PageIndex + @sys_Begin)) + ' ' + @sys_Key + ' FROM ' + @sys_Table + @new_where1 + @new_order2 +') w ' + @new_order1+') ' + @new_order2print(@sql)Exec(@sql)GO

posted on 2014-11-02 14:58 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/4069266.html

高效的SQLSERVER分页查询(推荐)相关推荐

  1. 高效的SQLSERVER分页查询

    Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询 ...

  2. 数据库:SQLServer分页查询整理

    作为程序员来说,与数据库打交道是十分频繁的分页查询是一个开发者必须掌握的基本知识点,目前整理了下面三种SQLServer分页查询语句的写法,仅供参考. 一.Top Not IN 方式(查询靠前的数据较 ...

  3. 三种SQLServer分页查询语句笔记

    作为程序员来说,与数据库打交道是十分频繁的分页查询是一个开发者必须掌握的基本知识点,目前整理了下面三种SQLServer分页查询语句的写法,仅供参考. 一.Top Not IN 方式(查询靠前的数据较 ...

  4. Oracle、 Mysql 、 SQLserver 分页查询

    MYSQL 分页最简单了. SELECT * FROM Account  WHERE (usertype='base' or usertype='home' or usertype='salse')  ...

  5. Sqlserver分页查询语句

    Sql server分页查询语句 PageSize:每页显示几条数据 pageNumber:当前页索引 T为表 注:通常pageNumber索引从零开始 select * from t where I ...

  6. SQLServer分页查询

    OFFSET x ROW FETCH NEXT y ROWS ONLY; 使用OFFSET是SQLServer2012新具有的分页功能,主要功能是从第x条数据开始共取y数据.但是其必须跟在Order ...

  7. 你还不会ElasticsSearch分页查询?那你看这一篇就够了,快拿走吧

    关注.星标下方公众号[ 大数据之美 ],和你一起成长 原文链接:你还不会ElasticsSearch分页查询?那你看这一篇就够了,快拿走吧 引言 我们使用mysql的时候经常遇到分页查询的场景,在my ...

  8. mysql读取第3条记录_sql查询(三)之分页查询

    分页查询这个内容基本上是个项目都会用的到的东西,面试也会问到的, 平常项目中老是百度用法,这些写博客来总结一下,省的老是百度. 现在主流的关系型数据的分页实现还是有点差别的,以oracle.mysql ...

  9. Sqlserver 数据库分页查询(三种方式)

    --第一种分页:sqlserver 2000-sqlserver2005 --假设:每页显示5条, 当前页:1  则查询1-5 --不等于前5条的前5条 select top 5 * from  St ...

  10. ORACLE分页查询SQL语法——最高效的分页

    --1:无ORDER BY排序的写法.(效率最高) --(经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!) SELECT *FROM (SELECT ...

最新文章

  1. springboot集成swagger2多模块中文配置详细步骤,解决集成mybatis或mybatis-plus无法正常使用问题
  2. 站长图卦:每天坚持搬砖 定有美好明天
  3. Spring与Oauth2整合示例 spring-oauth-server
  4. java.lang.NoSuchMethodError: org.apache.flink.table.api.TableColumn.isGenerated()Z
  5. SAP CRM WebClient UI表格编辑模式的调试明细
  6. Facebook开源动画库 POP-POPBasicAnimation运用
  7. jpa embedded_JPA @Embeddable和@Embedded
  8. 用python读取股票价格_Python读取文件并给出股票价格
  9. Android三级目录、ListView单选/GridView单选、ListView多选/GridView多选
  10. 解决docker network create --subnet报错的问题:Error response from daemon: Pool overlaps with other one on th
  11. canvas绘制出货单
  12. java自动洗扑克牌算法_扑克牌 洗牌算法 的java实现
  13. 相机镜头选择:相机焦距、视场角和景深(可视距离)之间的关系
  14. Pomodoro方法
  15. 语法树,前缀式,中缀式,后缀式
  16. ES8新增的常用语法
  17. Monte-Carlo Dropout,蒙特卡罗 dropout
  18. 创业公司第三方服务精选(移动互联网版)
  19. 安装C3D v1.0提取视频特征
  20. js中的reduce函数详细解释

热门文章

  1. Blender Reference Manual 欢迎使用Blender手册!
  2. AHOI2018训练日程(3.10~4.12)
  3. 浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用
  4. [转]SDI模式下,在视图中添加按钮
  5. 雷林鹏分享:PHP XML Parser 函数
  6. Project configuration is not up-to-date with pom.xml. Run Maven-Update Project or use Quick Fix
  7. 【7001】n阶法雷序列
  8. unigui web app之title buttons
  9. 《Java核心技术卷一》学习笔记(一)
  10. c#2.0语法新关键字 partial