使用SQL Server 2005 新的语法ROW_NUMBER()进行分页的两种不同方式的性能比较
相比在SQL Server 2000 中使用的分页方式,在SQL Server 2005中使用新的语法ROW_NUMBER()来分页效率要高出很多,但是很多人在使用ROW_NUMBER()这种分页方式时,使用的方法并不正确,以下列出不正确的和正确的做法并做简单分析:
首先假设我们已经创建了如下的表和索引并初始化了100万条数据:
CREATE TABLE [dbo].[Users]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NULL,
[Test] [nchar](10) NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
(
[ID] ASC
) ON [PRIMARY]
) ON [PRIMARY] CREATE UNIQUE NONCLUSTERED INDEX [Inx_Name] ON [dbo].[Users]
(
[Name] ASC
) ON [PRIMARY] DECLARE @index INT
SET @index=0
WHILE @index<1000000
BEGIN
INSERT INTO [dbo].[Users]([Name],[Test]) values(@index,'walkingp')
SET @index = @index + 1
END
不正确的使用方式(查出所有数据后再排序):
SELECT ID,Name,Test
FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RowNum,*
FROM dbo.Users
) AS T
WHERE RowNum BETWEEN 5000 AND 5100
正确的使用方式如下(查出主键进行排序过滤,然后使用过滤后的主键来查找数据):
SELECT A.ID,A.Name,A.Test
FROM dbo.Users AS A
INNER JOIN
(SELECT RowNum,ID
FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RowNum,ID
FROM dbo.Users) AS T
WHERE RowNum BETWEEN 4000 AND 4100) as B
ON A.ID = B.ID
ORDER BY B.RowNum
以下具体分析:
SET STATISTICS IO ON
SET STATISTICS TIME ON
GO PRINT 'Error.5000-------------------------'
DECLARE @time DATETIME
DECLARE @ms INT
SET @time= GETDATE() SELECT ID,Name,Test
FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RowNum,*
FROM dbo.Users) AS T
WHERE RowNum BETWEEN 5000 AND 5100 SET @ms=DATEDIFF(ms,@time,GETDATE())
PRINT @ms--毫秒数
GO PRINT 'Right.5000-------------------------'
DECLARE @time DATETIME
DECLARE @ms INT
SET @time= GETDATE() SELECT A.ID,A.Name,A.Test
FROM dbo.Users AS A
INNER JOIN
(SELECT RowNum,ID
FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RowNum,ID
FROM dbo.Users) AS T
WHERE RowNum BETWEEN 5000 AND 5100) AS B
ON A.ID = B.ID
ORDER BY B.RowNum SET @ms=DATEDIFF(ms,@time,GETDATE())
PRINT @ms--毫秒数
GO PRINT 'Error.500000-------------------------'
DECLARE @time DATETIME
DECLARE @ms INT
SET @time= GETDATE() SELECT ID,Name,Test
FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RowNum,*
FROM dbo.Users) AS T
WHERE RowNum BETWEEN 500000 AND 500100 SET @ms=DATEDIFF(ms,@time,GETDATE())
PRINT @ms--毫秒数
GO PRINT 'Right.500000-------------------------'
DECLARE @time DATETIME
DECLARE @ms INT
SET @time= GETDATE() SELECT A.ID,A.Name,A.Test
FROM dbo.Users AS A
INNER JOIN
(SELECT RowNum,ID
FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RowNum,ID
FROM dbo.Users) AS T
WHERE RowNum BETWEEN 500000 AND 500100) AS B
ON A.ID = B.ID
ORDER BY B.RowNum SET @ms=DATEDIFF(ms,@time,GETDATE())
PRINT @ms--毫秒数
GO PRINT 'Error.900000-------------------------'
DECLARE @time DATETIME
DECLARE @ms INT
SET @time= GETDATE() SELECT ID,Name,Test
FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RowNum,*
FROM dbo.Users) AS T
WHERE RowNum BETWEEN 900000 AND 900100 SET @ms=DATEDIFF(ms,@time,GETDATE())
PRINT @ms--毫秒数
GO PRINT 'Right.900000-------------------------'
DECLARE @time DATETIME
DECLARE @ms INT
SET @time= GETDATE() SELECT A.ID,A.Name,A.Test
FROM dbo.Users AS A
INNER JOIN
(SELECT RowNum,ID
FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RowNum,ID
FROM dbo.Users) AS T
WHERE RowNum BETWEEN 900000 AND 900100) AS B
ON A.ID = B.ID
ORDER BY B.RowNum SET @ms=DATEDIFF(ms,@time,GETDATE())
PRINT @ms--毫秒数
以下是SQL的统计信息:
Error.5000-------------------------
(101 row(s) affected)
Table 'Users'. Scan count 1, logical reads 15649, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 31 ms, elapsed time = 35 ms.
36
Right.5000-------------------------
(101 row(s) affected)
Table 'Users'. Scan count 1, logical reads 325, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 7 ms.
6
Error.500000-------------------------
(101 row(s) affected)
Table 'Users'. Scan count 1, logical reads 1532807, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 1797 ms, elapsed time = 1789 ms.
1786
Right.500000-------------------------
(101 row(s) affected)
Table 'Users'. Scan count 1, logical reads 1545, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 453 ms, elapsed time = 454 ms.
453
Error.900000-------------------------
(101 row(s) affected)
Table 'Users'. Scan count 1, logical reads 2758790, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 3266 ms, elapsed time = 3280 ms.
3273
Right.900000-------------------------
(101 row(s) affected)
Table 'Users'. Scan count 1, logical reads 2528, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 750 ms, elapsed time = 748 ms.
750
通过分析可以看出错误的使用方式逻辑读要比正确的使用方式的逻辑读大的多,而且页码越大读的越多,最终导致效率越来越差,这点也可以通过执行计划看出端倪。
希望对您有所帮助^_^。
使用SQL Server 2005 新的语法ROW_NUMBER()进行分页的两种不同方式的性能比较的更多相关文章
- 转载--SQL Server 2005的XQuery介绍
原文地址: http://bbs.51cto.com/thread-458009-1-1.html 引用: 摘要 本文介绍了SQL Server 2005能够支持的XQuery的各方面特性如FLW ...
- python常有模块:模块、引入语法、两种执行方式、模块搜索顺序
今天主要讲了以下几点:一.模块三问.定义及分类二.import和from的语法三.文件的两种执行方式及搜索顺序四.内置函数 一.模块.import和from的语法 1.什么是模块 模块是一堆功能函 ...
- sql server 2000 对应 sql server 2005的row_number()、rank()、DENSE_RANK( )、ntile( )等用法
转自CSDN:http://blog.csdn.net/htl258/article/details/4006717 SQL server 2005新增的几个函数,分别是row_number( ).r ...
- SQL Server 2005的几个新功能
SQL Server 2005相对于SQL Server 2000改进很大,有些还是非常实用的. 举几个例子来简单说明 这些例子我引用了Northwind库. 1. TOP 表达式 SQL Serv ...
- SQL SERVER 2005快捷键+visual studio 2008 快捷键
一.SQL SERVER 2005快捷键 快捷键 功能 CTRL + SHIF ...
- 浅析SQL Server 2005中的主动式通知机制
一.引言 在开发多人同时访问的Web应用程序(其实不只这类程序)时,开发人员往往会在缓存策略的设计上狠下功夫.这是因为,如果将这种环境下不常变更的数据临时存放在应用程序服务器或是用户机器上的话,可以避 ...
- SQL Server 2005的XML数据修改语言(XML DML)
转:http://www.microsoft.com/china/msdn/library/data/sqlserver/XMLDML.mspx?mfr=true 作为对XQuery语言的扩展,XML ...
- SQL server 2005 PIVOT运算符的使用
原文:SQL server 2005 PIVOT运算符的使用 PIVOT,UNPIVOT运算符是SQL server 2005支持的新功能之一,主要用来实现行到列的转换.本文主要介绍PIVOT运算符的 ...
- 【转】SQL SERVER 2005中如何获取日期(一个月的最后一日、上个月第一天、最后一天、一年的第一日等等)
在网上找到的一篇文章,相当不错哦O(∩_∩)O~ //C#本周第一天 int dayOfWeek = Convert.ToInt32(DateTime.Now.DayOfWeek ...
随机推荐
- 经常使用的webservice接口
Web Service 一些对外公开的网络服务接口 2011-10-29 14:12 商业和贸易: 1.股票行情数据 WEB 服务(支持香港.深圳.上海基金.债券和股票:支持多股票同一时候查询) En ...
- C如何获取文件夹下所有文件
http://baike.baidu.com/view/1186290.htm?fr=aladdin 使用io.h中的_findfirst,_findnext,_findclose,_finddata ...
- HTML5 面试中最常问到的 10 个问题
1. HTML5 新的 DocType 和 Charset 是什么?HTML5 现在已经不是 SGML 的子集,DocType 简化为: <!doctype h ...
- 将字符串写进txt中方式
try { File file = new File(filePath); PrintStream ps = new PrintStream(new FileOutputStream(file)); ...
- Android 换肤功能的实现(Apk插件方式)
一.概述 由于Android 没有提供一套统一的换肤机制,我猜可能是因为国外更注重功能和体验的原因 所以国内如果要做一个漂亮的换肤方案,需要自己去实现. 目前换肤的方法大概有三种方案: (1)把皮肤资 ...
- Spring-boot访问MongoDB
1.访问配置信息 package hello; import org.springframework.context.annotation.Bean; import org.springframewo ...
- ios 图片截取功能 图片拼接功能
截取整个view: -(UIImage*)captureView:(UIView *)theView{ CGRect rect = theView.frame; if ([theView isKind ...
- GitHub帮助文档翻译1——helloWorld
工欲善其事必先利其器 ,都不知道 GitHub到底是什么,还怎么玩?因为总是会读了第一句就忘了下一句,形成不了感觉,所以希望把读GitHub的帮助文档都翻译出来,总是看大段大段的东西,谁都会懵圈的.希 ...
- malloc函数的底层实现你是否清楚
malloc函数的底层实现你是否清楚 说起malloc函数,每个人都能说出它的功能,而且我们经常会用到,那么今天我要说的是关于malloc函数在编译器的底层实现,如果你对它的实现已经很清楚了,那么你可 ...
- Linux清空内存缓存
> /proc/sys/vm/drop_caches