`
netxdiy
  • 浏览: 714674 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

SQL Server 2012提供的OFFSET/FETCH NEXT与Row_Number()对比测试

 
阅读更多

SQL Server 2008中SQL应用系列--目录索引

前些天看到一篇文章《SQL Server 2012 - Server side paging demo using OFFSET/FETCH NEXT》,原文地址。作者在文中称,要SQL Server 2012使用OFFSET/FETCH NEXT分页,比SQL Server 2005/2008中的RowNumber()有显著改进。今天特地作了简单测试。现将过程分享如下:

附:我的测试环境为:
SQL Server 2012,命名实例

Microsoft SQL Server 2012 - 11.0.2100.60 (Intel X86)
Feb 10 2012 19:13:17
Copyright (c) Microsoft Corporation
Enterprise Edition on Windows NT 6.0 <X86> (Build 6002: Service Pack 2)

沿用上文的测试数据库和表:

IF OBJECT_ID('DemoPager2012') IS NOT NULL
DROP DataBase DemoPager2012
GO

CREATE Database DemoPager2012
GO

USE DemoPager2012
GO/*
Setup script to create the sample table and fill it with
sample data.
*/
IF OBJECT_ID('Customers','U') IS NOT NULL
DROP TABLE Customers

CREATE TABLE Customers ( CustomerID INT primary key identity(1,1),
CustomerNumber CHAR(4),
CustomerName VARCHAR(50),
CustomerCity VARCHAR(20) )
GOTRUNCATE table Customers
GO

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

/*****运用CTE递归插入,速度较快,邀月注***********************/
WITH Seq (num,CustomerNumber, CustomerName, CustomerCity) AS
(SELECT 1,cast('0000'as CHAR(4)),cast('Customer 0' AS NVARCHAR(50)),cast('X-City' as NVARCHAR(20))
UNION ALL
SELECT num + 1,Cast(REPLACE(STR(num, 4), ' ', '0') AS CHAR(4)),
cast('Customer ' + STR(num,6) AS NVARCHAR(50)),
cast(CHAR(65 + (num % 26)) + '-City' AS NVARCHAR(20))
FROM Seq
WHERE num <= 10000
)
INSERT INTO Customers (CustomerNumber, CustomerName, CustomerCity)
SELECT CustomerNumber, CustomerName, CustomerCity
FROM Seq
OPTION (MAXRECURSION 0)

插入1万条数据后,在SQL Server 2008 R2中执行Row_Number():
/*
Server side paging demo using ROW_NUMBER() - SQL Server
2005/2008 version.
*/

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GO


DECLARE @page INT, @size INT
SELECT @page = 3, @size = 10

;WITH cte AS (
SELECT TOP (@page * @size)
CustomerID,
CustomerName,
CustomerCity,
ROW_NUMBER() OVER(ORDER BY CustomerName ) AS Seq,
COUNT(*) OVER(PARTITION BY '') AS Total
FROM Customers
WHERE CustomerCity IN ('A-City','B-City')
ORDER BY CustomerName ASC
)
SELECT * FROM cte
WHERE seq BETWEEN (@page - 1 ) * @size + 1 AND @page * @size
ORDER BY seq;
GO

SET STATISTICS IO OFF ;
SET STATISTICS TIME OFF;
GO

SQL Server 2012中执行OFFSET/FETCH NEXT语句如下:

/*
Server side paging demo using the new enhancements added
in SQL Server 2012
*/
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GO


DECLARE @page INT, @size INT
SELECT @page = 3, @size = 10

SELECT
*,
COUNT(*) OVER(PARTITION BY '') AS Total
FROM Customers
WHERE CustomerCity IN ('A-City','B-City')
ORDER BY CustomerID
OFFSET (@page -1) * @size ROWS
FETCH NEXT @size ROWS ONLY;
GO

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
GO


在SQL Server 2012中执行如下语句:

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GO

DECLARE @page INT, @size INT
SELECT @page = 3, @size = 10

;WITH cte AS (
SELECT TOP (@page * @size)
CustomerID,
CustomerName,
CustomerCity,
ROW_NUMBER() OVER(ORDER BY CustomerName ) AS Seq,
COUNT(*) OVER(PARTITION BY '') AS Total
FROM Customers
WHERE CustomerCity IN ('A-City','B-City')
ORDER BY CustomerName ASC
)
SELECT * FROM cte
WHERE seq BETWEEN (@page - 1 ) * @size + 1 AND @page * @size
ORDER BY seq;


SELECT
*,
COUNT(*) OVER(PARTITION BY '') AS Total
FROM Customers
WHERE CustomerCity IN ('A-City','B-City')
ORDER BY CustomerID
OFFSET (@page -1) * @size ROWS
FETCH NEXT @size ROWS ONLY;
GO

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
GO


结论:无论是从逻辑读取数还是响应时间实际执行行数等关键参数看,SQL Server 2012提供的OFFSET/FETCH NEXT分页方式都比Row_Number()方式有了较大的提升。


邀月注:本文版权由邀月和CSDN共同所有,转载请注明出处。
助人等于自助! 3w@live.cn



分享到:
评论

相关推荐

    SQL Server 2012使用Offset/Fetch Next实现分页数据查询

    在SQL Server 2012中,为了更高效地实现数据分页查询,引入了`OFFSET ... FETCH NEXT ... ROWS ONLY`语法。在此之前,开发人员通常依赖`ROW_NUMBER()`窗口函数来达到同样的目的。这两种方法各有优缺点,下面将详细...

    row_number.rar_SQL中row_number用法_number

    例如,通过限制返回的行数(如`OFFSET n ROWS FETCH NEXT m ROWS ONLY`),可以获取特定页面的数据。 - **Top N查询**:快速获取表中的前N行或后N行数据,可以避免全表扫描,提高查询效率。 - **数据清理**:在...

    oracle rownum 的使用 和sqlserver有区别的!

    - SQL Server 中则通常采用 TOP 子句或 OFFSET/FETCH NEXT 子句来实现类似的功能: ```sql SELECT TOP 20 * FROM tab_name ORDER BY column_name; ``` 4. **性能考量:** - 使用 ROWNUM 进行分页查询时,需要...

    基于SQL Server的ASP.NET分页技术.pdf

    分页主要是通过SQL查询来实现的,常见的方法有两种:ROW_NUMBER()函数和OFFSET/FETCH语法。ROW_NUMBER()函数可以为查询结果集中的每一行赋予一个唯一的行号,然后根据这个行号进行分页;OFFSET/FETCH语法则提供了更...

    SQL Server代码实例分页效果

    总结来说,SQL Server提供了多种分页技术,包括`TOP`与`ORDER BY`,`ROW_NUMBER()`窗口函数,以及`OFFSET`和`FETCH NEXT`。在代码后台,可以编写通用的方法来封装这些查询,方便在各种场景下使用。合理地利用索引和...

    SqlServer数据库分页

    在SQL Server中,有两种主要的分页方法:`TOP`和`OFFSET-FETCH`,以及`ROW_NUMBER()`函数配合`WHERE`子句。 1. **TOP 和 OFFSET-FETCH**: - `TOP`关键字用于获取查询结果的前n行。例如,`SELECT TOP 10 * FROM ...

    Sql Server 2012 分页方法分析(offset and fetch)

    在SQL Server 2012中,`OFFSET` 和 `FETCH` 提供了一种更为高效且易用的分页解决方案。这两个关键字的引入是针对早期版本中如`ROW_NUMBER()`等分页方法的改进,尤其是在处理大数据量时,性能表现更佳。 1. `OFFSET`...

    海量数据查询sqlserver

    在SQL Server中,常见的分页方法有ROW_NUMBER()函数和OFFSET-FETCH关键字。ROW_NUMBER()函数可以为查询结果集中的每一行分配一个唯一的数字,然后通过这个数字进行分页。例如: ```sql SELECT * FROM ( SELECT ROW...

    千万级数据分页查询存储过程SQLServer

    SQL Server 2012及更高版本引入了`OFFSET-FETCH`,这提供了更直观的分页方式。它可以直接指定跳过多少行(OFFSET)以及获取多少行(FETCH)。例如: ```sql CREATE PROCEDURE GetPagedData (@pageNumber INT, @...

    SQL server 分页查询

    自SQL Server 2012起,引入了`OFFSET`和`FETCH`关键字,它们提供了一种更直观的分页查询方式。例如,如果我们想要获取前10页(每页10条记录)的数据,可以这样写: ```sql WITH CTE AS ( SELECT * FROM [Products...

    SQLServer分页.rar

    除了`OFFSET/FETCH`方法,SQL Server还支持使用`TOP`和`WITH TIES`配合`ROW_NUMBER()`函数进行分页,这种方法在某些情况下可能更高效: ```sql WITH CTE AS ( SELECT TOP (10 + @PageSize) *, ROW_NUMBER() OVER ...

    sql server 分页大全

    在SQL Server 2000中,由于没有内置的`OFFSET`和`FETCH`功能,我们可以使用`ROW_NUMBER()`函数配合`WHERE`子句来实现分页。首先,为每一行分配一个唯一的行号,然后根据这个行号进行筛选: ```sql WITH PagedData ...

    Sql server 分页存储过程的性能对比

    使用`ROW_NUMBER()`窗口函数可以为结果集中的每一行分配一个唯一的行号,结合`OFFSET`和`FETCH NEXT`语句实现分页。这种方法在SQL Server 2005及更高版本中被引入,性能通常较好,因为它避免了对整个结果集的排序和...

    SQL Server分页存储过程

    分页通常通过LIMIT或OFFSET/FETCH关键字来实现,但在SQL Server中,我们依赖的是TOP和ROW_NUMBER()函数的组合。存储过程是预编译的SQL代码集合,可以在需要时多次调用,提供了一种封装复杂查询和逻辑的方式。 创建...

    Sqlserver、Oracle、MySql、PostgreSql、SqlLite数据库差异

    - SQL Server 2012以上版本推荐使用 `OFFSET FETCH NEXT` 的方式。 - 2012以下版本可采用 `TOP NOT IN` 方法实现分页。 示例代码: ```sql -- 通用方法 SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY ...

    Page_SQL(Sqlserver_mysql_oracle_postgre).rar_PAGE_SQL_page

    在SQL Server中,通常使用`OFFSET`和`FETCH NEXT`关键字进行分页。例如,如果我们想获取第5页的数据,每页显示10条记录,可以编写以下查询: ```sql SELECT * FROM TableName ORDER BY ColumnName OFFSET 40 ...

    sql server 2000 分页存储过程,DB2分页存储过程,db2自动生成流水号存储过程

    在SQL Server 2000中,由于没有内置的OFFSET和FETCH NEXT功能,我们通常会使用`TOP`和`ORDER BY`结合`ROW_NUMBER()`函数来实现分页。以下是一个简单的例子: ```sql CREATE PROCEDURE GetPagedData @StartIndex INT...

    3个高效率sql分页存储过程

    ROW_NUMBER()是SQL Server中的一个窗口函数,它为每一行提供一个唯一的行号。我们可以利用这个功能来实现分页。以下是一个基础的存储过程示例: ```sql CREATE PROCEDURE GetPagedData @PageNumber INT, @...

Global site tag (gtag.js) - Google Analytics