相比在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()进行分页的两种不同方式的性能比较的更多相关文章

  1. 转载--SQL Server 2005的XQuery介绍

    原文地址: http://bbs.51cto.com/thread-458009-1-1.html   引用: 摘要 本文介绍了SQL Server 2005能够支持的XQuery的各方面特性如FLW ...

  2. python常有模块:模块、引入语法、两种执行方式、模块搜索顺序

    今天主要讲了以下几点:一.模块三问.定义及分类二.import和from的语法三.文件的两种执行方式及搜索顺序四.内置函数 一.模块.import和from的语法 1.什么是模块   模块是一堆功能函 ...

  3. 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 ...

  4. SQL Server 2005的几个新功能

    SQL Server 2005相对于SQL Server 2000改进很大,有些还是非常实用的. 举几个例子来简单说明 这些例子我引用了Northwind库. 1. TOP 表达式  SQL Serv ...

  5. SQL SERVER 2005快捷键+visual studio 2008 快捷键

    一.SQL SERVER 2005快捷键  快捷键                                       功能           CTRL       +       SHIF ...

  6. 浅析SQL Server 2005中的主动式通知机制

    一.引言 在开发多人同时访问的Web应用程序(其实不只这类程序)时,开发人员往往会在缓存策略的设计上狠下功夫.这是因为,如果将这种环境下不常变更的数据临时存放在应用程序服务器或是用户机器上的话,可以避 ...

  7. SQL Server 2005的XML数据修改语言(XML DML)

    转:http://www.microsoft.com/china/msdn/library/data/sqlserver/XMLDML.mspx?mfr=true 作为对XQuery语言的扩展,XML ...

  8. SQL server 2005 PIVOT运算符的使用

    原文:SQL server 2005 PIVOT运算符的使用 PIVOT,UNPIVOT运算符是SQL server 2005支持的新功能之一,主要用来实现行到列的转换.本文主要介绍PIVOT运算符的 ...

  9. 【转】SQL SERVER 2005中如何获取日期(一个月的最后一日、上个月第一天、最后一天、一年的第一日等等)

    在网上找到的一篇文章,相当不错哦O(∩_∩)O~ //C#本周第一天            int dayOfWeek = Convert.ToInt32(DateTime.Now.DayOfWeek ...

随机推荐

  1. 在Entity Framework中重用现有的数据库连接字符串

    本文转载:http://www.cnblogs.com/dudu/archive/2011/01/29/entity_framework_connection_string.html 如果EF在使用实 ...

  2. ASP终极防下载(转)

    自从搞ASP+ACCESS没少为避免数据库下载而伤过神,网上的奇淫技巧更是数不胜数,本文就是同大家共同探讨各路前辈的留下的秘笈并指中其中的优劣,最后为大家提供一种最佳的解决方案. 一.开篇 自从搞AS ...

  3. 分析Model2系统心得

    分析Model2系统心得 前言:观摩他人的项目,学到一些新的.实践经验呀!!! 1.  怎样使用字符串处理类?从页面获取的Form类或者字段取值时使用. 2.在验证用户身份时,先推断username, ...

  4. win10.10 激活

    最近几天一直有同学来找我说,为什么用密钥或kms神龙版都无法激活win8/8.1.win10,于是我就让这些同学给我截图,结果他们激活出错的信息基本都一样,都是错误:“0XC004F074 软件授权服 ...

  5. Jenkins 安装与配置

    1. 软件准备 a. 下载 jenkins.war:https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins. 本文以 Jenkins 为演示版 ...

  6. Helpers\Assets

    Helpers\Assets The assets helper is for loading CSS and JS files rather than writing out the full sc ...

  7. hadoop学习记录(零)

    这个博客开通快一年了,但是由于种种原因,始终没有能够养成定期更新的习惯. 最近完成了比赛的项目,向除了android开发以外再拓宽一下自己的技能树. 最近购买了<java8函数式编程>和& ...

  8. JAVA_Gson

    package com.qf.mobiletrain01; import java.util.List; import com.google.gson.Gson; import com.google. ...

  9. Redis集群

    一.Redis集群原理 集群技术是构建高性能网站架构的重要手段,试想在网站承受高并发访问压力的同时,还需要从海量数据中查询出满足条件的数据,并快速响应,我们必然想到的是将数据进行切片,把数据根据某种规 ...

  10. linux commond

    1  vi /etc/sysconfig/network-scripts/ifcfg-eth0     2  ifconfig    3  ping 172.22.14.59    4  ping 1 ...