用DataReader 分页与几种传统的分页方法的比较
2008-10-09 10:10
411 查看
用DataReader 分页与几种传统的分页方法的比较
作者:肖波[原文:/article/4689739.html]
对于数据库的分页,目前比较传统的方法是采用分页存储过程,其实用 DataReader 也可以实现分页,不需要写存储过程,实现效率上也比几种比较流行的分页方法要略快。
在开始将这个方法之前,让我们先创建一个简单的测试环境:
use Test
GO
if exists (select * from sysobjects where id = object_id('R_Student') and type = 'u')
drop table R_Student
GO
create table R_Student
(
Id nvarchar(64) Primary Key,
Class nvarchar(64) NOT NULL,
Age tinyint NOT NULL,
Sex tinyint NOT NULL
)
GO
Declare
@i int
set @i = 0;
while (@i < 1000000)
begin
insert R_Student values('Name' + Str(@i),'Class' + Str(@i), @i % 100, @i % 2)
set @i = @i + 1
end
通过上述语句创建一个简单的数据表,并插入100万条记录
DataReader 分页的方法:
说出来很简单,见下面程序 源码下载位置
public DataSet RangeQuery(string queryString, long first, long last)
if exists (select * from sysobjects where id = object_id('PagedProcUseROW_NUMBER') and type = 'p')
drop procedure PagedProcUseROW_NUMBER
GO
create procedure PagedProcUseROW_NUMBER
@currentpage int, -- page no
@pagesize int --page size
as
begin
WITH student AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY Id) AS 'RowNumber'
FROM r_student
)
SELECT *
FROM student
WHERE RowNumber BETWEEN (@currentpage-1)*@pagesize + 1 AND (@currentpage)*@pagesize;
end
GO
3. 通用分页存储过程
这个存储过程的出处:
http://www.cnblogs.com/Tracy-Chuang/archive/2006/10/16/530125.html
我稍微改了一点,去掉了一些功能,方便测试。
这个存储过程有一些缺点,比如不支持多字段主键,重复键的处理看似也有问题,不排序也不可以。单纯从效率看,
还是可以的。
if exists (select * from sysobjects where id = object_id('[spCommonPageData]') and type = 'p')
drop procedure [spCommonPageData]
GO
--http://www.cnblogs.com/Tracy-Chuang/archive/2006/10/16/530125.html
-- =============================================
-- Author: <张婷婷>
-- Create date: <2006-08-24>
-- Description: <通用分页存储过程>
-- =============================================
Create PROCEDURE [dbo].[spCommonPageData]
@Select NVARCHAR(500), -- 要查询的列名,用逗号隔开(Select后面From前面的内容)
@From NVARCHAR(200), -- From后的内容
@Where NVARCHAR(500) = NULL, -- Where后的内容
@OrderBy NVARCHAR(100) = NULL, -- 排序字段
@Key NVARCHAR(50), -- 分页主键
@Page INT, -- 当前页 ***计数从1开始***
@PageSize INT -- 每页大小
AS
BEGIN
SET NOCOUNT ON;
Declare @Sql nVarchar(1000), @Sql2 NVARCHAR(500)
--Alter By Tracy.Chuang 2006-08-21更改分页算法,采用比较最大值的方法
Set @Sql=
'Select Top '+Cast(@PageSize As
nVarchar(10))+' '+@Select+ ' From '+@From+ ' Where '+Case
IsNull(@Where,'') When '' Then '' Else @Where+' And ' End+
@Key+' >( Select ISNULL(MAX('+@Key+'), 0) AS MaxID
From (Select Top '+Cast(@PageSize*(@Page-1) As Varchar(10))+'
'+@Key+
' From '+@From+
Case IsNull(@Where,'') When '' Then '' Else ' Where '+@Where End+
' Order By '+@Key+') As T)'+
' Order By '+@Key+Case IsNull(@OrderBy,'') When '' Then '' Else
','+@OrderBy End
Exec(@Sql)
END
四种方法的效率比较。只做了一种条件下测试,其他条件大家有兴趣可以自己测。
PageSize = 10, 记录总数 100万,时间单位为毫秒
源码下载位置
作者:肖波[原文:/article/4689739.html]
对于数据库的分页,目前比较传统的方法是采用分页存储过程,其实用 DataReader 也可以实现分页,不需要写存储过程,实现效率上也比几种比较流行的分页方法要略快。
在开始将这个方法之前,让我们先创建一个简单的测试环境:
use Test
GO
if exists (select * from sysobjects where id = object_id('R_Student') and type = 'u')
drop table R_Student
GO
create table R_Student
(
Id nvarchar(64) Primary Key,
Class nvarchar(64) NOT NULL,
Age tinyint NOT NULL,
Sex tinyint NOT NULL
)
GO
Declare
@i int
set @i = 0;
while (@i < 1000000)
begin
insert R_Student values('Name' + Str(@i),'Class' + Str(@i), @i % 100, @i % 2)
set @i = @i + 1
end
通过上述语句创建一个简单的数据表,并插入100万条记录
DataReader 分页的方法:
说出来很简单,见下面程序 源码下载位置
public DataSet RangeQuery(string queryString, long first, long last)
if exists (select * from sysobjects where id = object_id('PagedProcUseROW_NUMBER') and type = 'p')
drop procedure PagedProcUseROW_NUMBER
GO
create procedure PagedProcUseROW_NUMBER
@currentpage int, -- page no
@pagesize int --page size
as
begin
WITH student AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY Id) AS 'RowNumber'
FROM r_student
)
SELECT *
FROM student
WHERE RowNumber BETWEEN (@currentpage-1)*@pagesize + 1 AND (@currentpage)*@pagesize;
end
GO
3. 通用分页存储过程
这个存储过程的出处:
http://www.cnblogs.com/Tracy-Chuang/archive/2006/10/16/530125.html
我稍微改了一点,去掉了一些功能,方便测试。
这个存储过程有一些缺点,比如不支持多字段主键,重复键的处理看似也有问题,不排序也不可以。单纯从效率看,
还是可以的。
if exists (select * from sysobjects where id = object_id('[spCommonPageData]') and type = 'p')
drop procedure [spCommonPageData]
GO
--http://www.cnblogs.com/Tracy-Chuang/archive/2006/10/16/530125.html
-- =============================================
-- Author: <张婷婷>
-- Create date: <2006-08-24>
-- Description: <通用分页存储过程>
-- =============================================
Create PROCEDURE [dbo].[spCommonPageData]
@Select NVARCHAR(500), -- 要查询的列名,用逗号隔开(Select后面From前面的内容)
@From NVARCHAR(200), -- From后的内容
@Where NVARCHAR(500) = NULL, -- Where后的内容
@OrderBy NVARCHAR(100) = NULL, -- 排序字段
@Key NVARCHAR(50), -- 分页主键
@Page INT, -- 当前页 ***计数从1开始***
@PageSize INT -- 每页大小
AS
BEGIN
SET NOCOUNT ON;
Declare @Sql nVarchar(1000), @Sql2 NVARCHAR(500)
--Alter By Tracy.Chuang 2006-08-21更改分页算法,采用比较最大值的方法
Set @Sql=
'Select Top '+Cast(@PageSize As
nVarchar(10))+' '+@Select+ ' From '+@From+ ' Where '+Case
IsNull(@Where,'') When '' Then '' Else @Where+' And ' End+
@Key+' >( Select ISNULL(MAX('+@Key+'), 0) AS MaxID
From (Select Top '+Cast(@PageSize*(@Page-1) As Varchar(10))+'
'+@Key+
' From '+@From+
Case IsNull(@Where,'') When '' Then '' Else ' Where '+@Where End+
' Order By '+@Key+') As T)'+
' Order By '+@Key+Case IsNull(@OrderBy,'') When '' Then '' Else
','+@OrderBy End
Exec(@Sql)
END
四种方法的效率比较。只做了一种条件下测试,其他条件大家有兴趣可以自己测。
PageSize = 10, 记录总数 100万,时间单位为毫秒
分页方法 | 第1页 | 第10页 | 第100页 | 第1000页 | 第10000页 | 第100000页 |
二次 Top | 4 | 7 | 404 | 28 | 271 | 3926 |
ROW_NUMBER | 1 | 1 | 2 | 12 | 108 | 3594 |
通用分页 | 1 | 1 | 1 | 10 | 82 | 3487 |
DataReader | 0 | 0 | 1 | 9 | 91 | 3380 |
相关文章推荐
- 用DataReader 分页与几种传统的分页方法的比较
- 用DataReader 分页与几种传统的分页方法的比较
- 用DataReader 分页与几种传统的分页方法的比较
- 用DataReader 分页与几种传统的分页方法的比较 [转]
- 用DataReader 分页与几种传统的分页方法的比较
- 用DataReader 分页与几种传统的分页方法的比较
- 用DataReader 分页与几种传统的分页方法的比较
- 几种分页方法效率比较
- Asp.net 几种分页方法效率比较
- 几种分页方法效率比较
- oracle几种分页方法效率比较。
- Asp.net 几种分页方法效率比较
- SqlServer 几种分页方法比较
- 分页实现方法的性能比较
- 几种xml读取方法比较
- C#抽象工厂模式的几种实现方法及比较(转载)
- 几种任务调度的 Java 实现方法与比较
- 浅谈SQL Server2005的几种分页方法
- 几种常见SQL分页方式效率比较