SQL Server 中的三种分页方式
USE tempdb
GO
SET NOCOUNT ON --创建表结构
IF OBJECT_ID(N'ClassB', N'U') IS NOT NULL
DROP TABLE ClassB
GO
CREATE TABLE ClassB(ID INT PRIMARY KEY, Name VARCHAR(16), CreateDate DATETIME, AID INT, Status INT)
CREATE INDEX IDX_CreateDate ON ClassB(CreateDate)
CREATE INDEX IDX_AID ON ClassB(AID)
GO --插入测试数据
DECLARE @ID INT
SET @ID = 1
WHILE @ID <= 100000
BEGIN
INSERT INTO ClassB VALUES(@ID, 'fx', GETDATE(), @ID % 20, @ID % 20)
SET @ID = @ID + 1
END --统计总行数
SELECT 'ClassB' AS ClassB, count(1) AS Count FROM ClassB
查询条件如下:根据CreateDate倒序排序,CreateDate一致时按照ID倒序;时间区间在2014-07-13和2014-07-14之间;每页20条,当前页数第3页;
方案A:双Top,取出之前页的所有ID后,使用NOT IN排除这些ID进行查询,这是性能最差一种,因为他使用相同的查询谓词,查询了两次数据,且两次排序;
DECLARE @page_size INT = 20;
DECLARE @page_index INT = 3;
--A: 双Top:取出之前页的所有ID后,使用NOT IN排除这些ID进行查询,性能最差
WITH ID_List_Excluded AS
(
SELECT TOP (@page_size * (@page_index - 1)) ID FROM ClassB WHERE CreateDate BETWEEN '2014-07-13' AND '2014-07-14'
ORDER BY CreateDate DESC, ID DESC
)
SELECT TOP (@page_size) * FROM ClassB WHERE ID NOT IN (SELECT ID FROM ID_List_Excluded) AND CreateDate BETWEEN '2014-07-13' AND '2014-07-14'
ORDER BY CreateDate DESC, ID DESC;
表 'ClassB'。扫描计数 2,逻辑读取 136 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 1,逻辑读取 197 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
查询页数越靠后逻辑读取,下面是查询第30页的逻辑读取情况:
表 'ClassB'。扫描计数 2,逻辑读取 1243 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 1,逻辑读取 2574 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
方案B:ROW_NUMBER,取出截止到当前页所有符合查询谓词的记录,并给每条记录加上序号,然后根据序号查询,性能次之;
DECLARE @page_size INT = 20;
DECLARE @page_index INT = 3;
--B: ROW_NUMBER:取出截至到当前页所有符合查询谓词的记录,并给每条记录加上序号,然后根据序号查询,性能次之
WITH NewClassB AS
(
SELECT TOP (@page_size * @page_index) ROW_NUMBER() OVER (ORDER BY CreateDate DESC, ID DESC) AS ROWID, * FROM ClassB
WHERE CreateDate BETWEEN '2014-07-13' AND '2014-07-14'
)
SELECT TOP (@page_size) * FROM NewClassB
WHERE ROWID BETWEEN (@page_size * (@page_index - 1) + 1) AND (@page_size * @page_index);
表 'ClassB'。扫描计数 1,逻辑读取 134 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
方案B已经比方案A快了近一倍,少了一个Worktable,同样,page_index越大,扫描次数越多,因为子查询中要查询多余的(之前页)数据和字段,下面是查询第30页时的IO读取情况;
表 'ClassB'。扫描计数 1,逻辑读取 1241 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
方案C:双Top,取出截止到当前页为止的所有的ID,去掉之前页的ID,然后根据ID(通常是主键)作常规查询,性能最优;
DECLARE @page_size INT = 20;
DECLARE @page_index INT = 3;
WITH ID_List AS
(
SELECT TOP (@page_size * @page_index) ID FROM ClassB
WHERE CreateDate BETWEEN '2014-07-13' AND '2014-07-14'
ORDER BY CreateDate DESC, ID DESC
)
,ID_List_Current AS
(
SELECT ID FROM ID_List WHERE ID NOT IN(SELECT TOP (@page_size * (@page_index - 1)) ID FROM ID_List)
)
SELECT * FROM ClassB WHERE ID IN (SELECT ID FROM ID_List_Current);
表 'ClassB'。扫描计数 2,逻辑读取 52 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
查询第30页的数据仅比查询第3页的数据多出两次逻辑读取,方案C和B的唯一在于:子查询中的查询列,方案B中返回了所有字段,所有要通过聚集索引走lookup,而方案C直接返回索引键即可。
表 'ClassB'。扫描计数 2,逻辑读取 54 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
SQL Server 中的三种分页方式的更多相关文章
- SQL Server中的三种Join方式
1.测试数据准备 参考:Sql Server中的表访问方式Table Scan, Index Scan, Index Seek 这篇博客中的实验数据准备.这两篇博客使用了相同的实验数据. 2.SQ ...
- Asp.Net中的三种分页方式
Asp.Net中的三种分页方式 通常分页有3种方法,分别是asp.net自带的数据显示空间如GridView等自带的分页,第三方分页控件如aspnetpager,存储过程分页等. 第一种:使用Grid ...
- 浅谈SQL Server中的三种物理连接操作
简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...
- SQL Server中的三种物理连接操作
来源:https://msdn.microsoft.com/zh-cn/library/dn144699.aspx 简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Out ...
- 浅谈SQL Server中的三种物理连接操作(HASH JOIN MERGE JOIN NESTED LOOP)
简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...
- 浅谈SQL Server中的三种物理连接操作(Nested Loop Join、Merge Join、Hash Join)
简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...
- Asp.Net中的三种分页方式总结
本人ASP.net初学,网上找了一些分页的资料,看到这篇文章,没看到作者在名字,我转了你的文章,只为我可以用的时候方便查看,2010的文章了,不知道这技术是否过期. 以下才是正文 通常分页有3种方法, ...
- Sql Server 常见的几种分页方式
⒈offset fetch next方式[SqlServer2012及以上版本支持][推荐] select * from T_User order by id offset rows /*(页数-1) ...
- SQL Server中数据库文件的存放方式,文件和文件组
原文地址:http://www.cnblogs.com/CareySon/archive/2011/12/26/2301597.html SQL Server中数据库文件的存放方式,文件和文件组 ...
随机推荐
- 一个小应用的dbcp和c3p0配置实例
以下是一个小应用的数据库连接池配置,包括DBCP和C3P0的配制方法 因为是小应用,完全不涉及访问压力,所以配置上采取尽量节约数据库资源的方式 具体要求如下:初始化连接数为0连接不够,需要新创建时,每 ...
- OpenCV码源笔记——RandomTrees (二)(Forest)
源码细节: ● 训练函数 bool CvRTrees::train( const CvMat* _train_data, int _tflag, cons ...
- 如何写科技文章的讨论discussion部分
众所周知,讨论部分是在结合自己的研究结果基础上,对整个文章的结论的提炼和升华.这一部分是整个论文的精,往往点睛作用. 同时,很多杂志要求结果和讨论分开,这也就更突出了写好讨论的重要性. 那么,我们应该 ...
- LA 6042 Bee Tower 记忆化搜索
一开始读漏了很多细节,用递推写死活跑不出样例. 把题目中的细节列一下吧,状态方程很好推,改成记忆化搜索之后代码也很清晰. 1.蜜蜂需要到最高的塔去,最高的塔可能不止一个,抵达任意一个即可. 2.蜜蜂每 ...
- OGG-00782 - OGG 11.2.1.0.2 FOR Windows x64 Microsoft SQL Server
OS ENV:主机名: WIN-NO42QRNPMFAOS 名称: Microsoft Windows Server 2008 R2 Datacenter OS ...
- Hadoop1.x与Hadoop2的区别
转自:http://blog.csdn.net/fenglibing/article/details/32916445 六.Hadoop1.x与Hadoop2的区别 1.变更介绍 Hadoop2相比较 ...
- 高斯消元 分析 && 模板 (转载)
转载自:http://hi.baidu.com/czyuan_acm/item/dce4e6f8a8c45f13d7ff8cda czyuan 先上模板: /* 用于求整数解得方程组. */ #inc ...
- 解析UML9种图的作用
本文和大家重点讨论一下UML9种图的概念,UML中有五类图,共有9种图形,每种图形都有各自的特点,下面就让我们一起来看一下这些图形特点的详细介绍吧. UML9种图简介 1.用例图 说明的是谁要使用系统 ...
- Delphi反汇编内部字符串处理函数/过程不完全列表
Delphi反汇编内部字符串处理函数/过程不完全列表 名称 参数 返回值 作用 等价形式 / 备注 _PStrCat EAX :目标字符串 EDX :源字符串 EAX 连接两个 Pascal 字符 ...
- I.MX6 Android U-blox miniPCI 4G porting
/************************************************************************** * I.MX6 Android U-blox m ...