SQL Server分页查询方法整理
SQL Server数据库分页查询一直是SQL Server的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID、YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YEAR无索引,SQL Server版本:SQL Server 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]
GO CREATE 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 --页大小
AS SET NOCOUNT ON
SET ANSI_WARNINGS ON IF @sys_PageSize < 0 OR @sys_PageIndex < 0
BEGIN
RETURN
END DECLARE @new_where1 NVARCHAR(3000)
DECLARE @new_order1 NVARCHAR(100)
DECLARE @new_order2 NVARCHAR(100)
DECLARE @Sql NVARCHAR(4000)
DECLARE @SqlCount NVARCHAR(4000) DECLARE @Top int if(@sys_Begin <=0)
set @sys_Begin=0
else
set @sys_Begin=@sys_Begin-1 IF ISNULL(@sys_Where,'') = ''
SET @new_where1 = ' '
ELSE
SET @new_where1 = ' WHERE ' + @sys_Where IF ISNULL(@sys_Order,'') <> ''
BEGIN
SET @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
BEGIN
SET @new_order1 = ' ORDER BY ID DESC'
SET @new_order2 = ' ORDER BY ID ASC'
END SET @SqlCount = 'SELECT @RCount=COUNT(1),@PCount=CEILING((COUNT(1)+0.0)/'
+ CAST(@sys_PageSize AS NVARCHAR)+') FROM ' + @sys_Table + @new_where1 EXEC SP_EXECUTESQL @SqlCount,N'@RCount INT OUTPUT,@PCount INT OUTPUT',
@RCount OUTPUT,@PCount OUTPUT IF @sys_PageIndex > CEILING((@RCount+0.0)/@sys_PageSize) --如果输入的当前页数大于实际总页数,则把实际总页数赋值给当前页数
BEGIN
SET @sys_PageIndex = CEILING((@RCount+0.0)/@sys_PageSize)
END set @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_order2 print(@sql) Exec(@sql) GO
SQL Server分页查询方法整理的更多相关文章
- CASE函数 sql server——分组查询(方法和思想) ref和out 一般处理程序结合反射技术统一执行客户端请求 遍历查询结果集,update数据 HBuilder设置APP状态栏
CASE函数 作用: 可以将查询结果集的某一列的字段值进行替换 它可以生成一个新列 相当于switch...case和 if..else 使用语法: case 表达式/字段 when 值 then ...
- 优化SQL Server数据库查询方法
SQL Server数据库查询速度慢的原因有很多,常见的有以下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列 ...
- SQL Server分页查询进化史
分页查询一直SQL Server的一个硬伤,就是是经过一些进化,比起MySql的limit还是有一些差距. 一.条件过滤(适应用所有版本) 条件过滤的方法有很多,而思路就是利用集合的差集选择出目标集合 ...
- SQL SERVER 分页查询
Sqlserver数据库分页查询一直是Sqlserver的短板. 但现在不是了. 自从有了它. 一口气上十楼. 官方语法说明示例: https://technet.microsoft.com/zh-c ...
- sql server——分组查询(方法和思想)
思想 先排序在汇总 sql server里分组查询通常用于配合聚合函数,达到分类汇总统计的信息.而其分类汇总的本质实际上就是先将信息排序,排序后相同类别的信息会聚在一起,然后通过需求进行统计计算. 使 ...
- SQLServer分页查询方法整理以及批量插入操作SqlBulkCopy
分页查询 通用方法:sqlserver 2005 + ROW_NUMBER() OVER()方式: ; TOP NOT IN方式 : ID FROM TripDetail ORDER BY ID) O ...
- Oracle分页查询和SQL server分页查询总结
分页查询是项目中必不可少的一部分,难倒是不难,就是这些东西,长时间不用,就忘的一干二净了.今天特此总结一下这两款数据库分页查询的实现过程(只记录效率比较高的) 一.Oracle中的分页查询 1.通用分 ...
- sql server分页查询
1.引言 在列表查询时由于数据量非常多,一次性查出来会非常慢,就算一次查出来了,也不能一次性显示给客户端,所以要把数据进行分批查询出来,每页显示一定量的数据,这就是数据要分页. 2.常用的数据分页方法 ...
- SQL Server分页查询存储过程
--分页存储过程create PROCEDURE [dbo].[commonPagination]@columns varchar(500), --要显示的列名,用逗号隔开 @tableName va ...
随机推荐
- CAP理论与MongoDB一致性、可用性的一些思考
大约在五六年前,第一次接触到了当时已经是hot topic的NoSql.不过那个时候学的用的都是mysql,Nosql对于我而言还是新事物,并没有真正使用,只是不明觉厉.但是印象深刻的是这么一张图片( ...
- Oracle listener服务启动后又停止的解决方案
这是Oracle监听服务.忘了说我的版本是Oracle10g. 我装完Oracle数据库之后,然后用第三方工具plsql去连接,提示no listener,首先我反复检查tnsnames.ora配置文 ...
- python之 centos6.7下 python 3.5.2、Django-1.9 安装
在linux6.5中已经自带了python 2 .python 2.6 ,并且yum程序使用的就是自带的python,所以系统自带的python不要随意卸载否则可能导致yum用不了. 测试环境:cen ...
- Open vSwitch中的datapath flow匹配过程
看OVS2.7的datapath表项匹配是一件很蛋疼的事情 数据结构看不懂 匹配算法经过了多次演进,已经有点复杂了,看代码完全看不懂,我能怎么办,我也很绝望啊! 2.1之前精确匹配时代,匹配过程是 ...
- Java中关键词之this,super的使用
一.this关键词介绍. 说明:该知识点仅仅限于本人对其了解的范围. package com.study.java.oop; /** * 核心点:"this是指向对象本身的一个指针" ...
- Java中设计模式之生产者消费者模式-4
引言 生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区.其中一个是生产者,用于将消息放入缓冲区:另 ...
- Ubuntu环境下 matplotlib 图例中文乱码
最近做了一个最小二乘法的代码编写并用 matplotlib 绘制了一张图,但是碰到了中文乱码问题.简单搜索之后,发现有人总结出了比较好的方案,亲测可行.推荐给大家. 本文前提条件是 已经 安装好 ma ...
- 用WebStorm创建Express项目时出现:express version is unavailable
那是因为在npm的配置文件中使用了代理: 方式一:查看配置:npm config list如果有:registry = "https://registry.npm.taobao.org/&q ...
- Hadoop 2.7 伪分布式环境搭建
1.安装环境 ①.一台Linux CentOS6.7 系统 hostname ipaddress subnet mask ...
- python爬虫 模拟登陆校园网-初级
最近跟同学学习爬虫的时候看到网上有个帖子,好像是山大校园网不稳定,用py做了个模拟登陆很有趣,于是我走上了一条不归路..... 先上一张校园网截图 首先弄清一下模拟登陆的原理: 1:服务器判定浏览器登 ...