漂泊雪狼的博客
思考,讨论,分享C#,JavaScript,.NET,Oracle,SQL Server……技术
posts - 50, comments - 267, trackbacks - 9, articles - 10
【续】用ObjectDataSource实现自定义分页的心得总结,几种分页方法的性能对比
Posted on 2007-06-12 15:22
漂泊雪狼
阅读(3423)
评论(9)
编辑
收藏
在《用ObjectDataSource实现自定义分页的心得总结》中,在SQL Server中使用双Top查询,后来用“事件探查器”进行性能对比,发现在SQL Server 2005中使用RowNumber函数的方法更有效;在SQL Server 2000中无法使用RowNumber函数,但是数据量较大时,双Top查询速度很慢,排序的字段若没有建立索引后果更加糟糕,其实在SQL Server 2000中,可以巧妙的使用SET ROWCOUNT和表变量来实现自定义分页,如下是一个参考示例:
利用表变量分页
1
CREATE
PROCEDURE
usp_PagedResults_New_Rowcount
2
(
3
@startRowIndex
int
,
4
@maximumRows
int
5
)
6
AS
7
8
DECLARE
@TempItems
TABLE
9
(
10
ID
int
IDENTITY
,
11
EmployeeID
int
12
)
13
14
DECLARE
@maxRow
int
15
16
17
SET
@maxRow
=
(
@startRowIndex
+
@maximumRows
)
-
1
18
19
SET
ROWCOUNT
@maxRow
20
21
INSERT
INTO
@TempItems
(EmployeeID)
22
SELECT
EmployeeID
23
FROM
Employees
24
ORDER
BY
EmployeeID
25
26
SET
ROWCOUNT
@maximumRows
27
28
SELECT
e.
*
, d.
[
Name
]
as
DepartmentName
29
FROM
@TempItems
t
30
INNER
JOIN
Employees e
ON
31
e.EmployeeID
=
t.EmployeeID
32
INNER
JOIN
Departments d
ON
33
d.DepartmentID
=
e.DepartmentID
34
WHERE
ID
>=
@startRowIndex
35
36
SET
ROWCOUNT
0
37
38
GO
在上面的代码中,如果EmployeeID是唯一的(一般在数据库设计的时候推荐在表中加一个自增列的字段来取代它),可以不用表变量切性能可进一步得到优化,具体代码如下:
优化的分页程序
1
CREATE
PROCEDURE
[
dbo
]
.
[
usp_PageResults_NAI
]
2
(
3
@startRowIndex
int
,
4
@maximumRows
int
5
)
6
AS
7
8
DECLARE
@first_id
int
,
@startRow
int
9
10
--
得到开始一笔记录的employeeID
11
SET
ROWCOUNT
@startRowIndex
12
SELECT
@first_id
=
employeeID
FROM
employees
ORDER
BY
employeeid
13
14
--
--从开始一笔记录的employeeID取出数量等于每页的记录的结果集
15
16
SET
ROWCOUNT
@maximumRows
17
18
SELECT
e.
*
, d.name
as
DepartmentName
19
FROM
employees e
20
INNER
JOIN
Departments D
ON
21
e.DepartmentID
=
d.DepartmentID
22
WHERE
employeeid
>=
@first_id
23
ORDER
BY
e.EmployeeID
24
25
SET
ROWCOUNT
0
26
27
GO
28
29
30
在SQL Server 2005和Oracle 9i后的版本中可以分别使用ROWNUMBER和ROWNUM来进行分页,并能获得较好的性能,以SQL Server 2005为例,一般的做法如下:
1
SELECT
2
FROM
3
(
SELECT
4
ROW_NUMBER()
OVER
(
ORDER
BY
ColumnName)
as
RowNum
5
FROM
Employees e
6
)
as
DerivedTableName
7
WHERE
RowNum
BETWEEN
@startRowIndex
AND
(
@startRowIndex
+
@maximumRows
)
-
1
8
9
但是有一个小问题,如果最里面的一层查询有重复值,上面的排序将会出现问题,最好将代码优化成如下形式:
1
SELECT
2
(
3
SELECT
,
4
ROW_NUMBER()
OVER
(
ORDER
BY
ColumnName)
as
RowNum
5
FROM
6
(
SELECT
DISTINCT
7
FROM
Employees e
8
INNER
JOIN
f
9
ON
e.id
=
f.id
10
)
AS
DerivedTableName
11
)
AS
Temp
12
WHERE
RowNum
BETWEEN
@startRowIndex
AND
(
@startRowIndex
+
@maximumRows
)
-
1
之所以要这么做是为了是DISTINCT发挥作用,因为在SQL Server2005中DISTINCT和ROW_NUMBER()一起使用,DISTINCT将不能过滤掉重复的记录,在Oracle中DISTINCT和ROWNUM也会同样出现这样的问题,这些都是本人在实际项目中遇到的问题并总结出来的,或许你有更好的方法,可以在我的博客中留言,谢谢!
参考文章:
http://aspnet.4guysfromrolla.com/articles/031506-1.aspx
绿色通道:
好文要顶
关注我
收藏该文
与我联系
Feedback
#1楼
回复
引用
查看
2007-06-12 16:26
by
henry
其实直接用DataReader分即省事又方便,效率和ROWNUMBER或ROWNUM差不多.
#2楼
[
楼主
]
回复
引用
查看
2007-06-12 16:29
by
漂泊雪狼
to henry :
用DataReader 而不用Rownumber和ROWNUM,你如何控制读取的起至位置?写在业务逻辑中吗?
#3楼
回复
引用
查看
2007-06-12 16:36
by
henry
@漂泊雪狼
既然有开始行和结束行难道Read不成(这样的分页是和数据库无关性的),
其实ROWNUMBER或ROWNUM做的工作和游标差不多,只是MSSQL和Oracle定义这样的东西在编写SQL方便一点,难首你以为从100开台就不会把0-99的读出来?这个东西分页的效率还会受读取字段数影响。
#4楼
[
楼主
]
回复
引用
查看
2007-06-12 16:50
by
漂泊雪狼
用ROWNUMBER或ROWNUM绝对比游标的效率要高,用DataReader可以实现你所的分页,但那是在逻辑层控制DataReader的读取操作,分页的负担给了web服务器,用存储过程分页可以减轻web服务器负担,让数据库服务器来做这些,且根据不同的数据库提供不同的分页实现方式,可以提高程序的性能。
#5楼
回复
引用
查看
2007-06-12 17:10
by
henry
@漂泊雪狼
用ROWNUMBER或ROWNUM绝对比游标的效率要高?你真的实践过?
我做一个实践有一个一百W记录的表20个字段,用游标遍历主索引分页然后再根据当前页的主索引重新获取记录,
越往后走游标这种分页比ROWNUMBER或ROWNUM分页的效率按倍数增长。
还有一个问题,你认为数据库集群方便还是webapp集群方便?
#6楼
回复
引用
查看
2007-06-12 17:26
by
neuhawk
我们是用存储过程~~~~~~~~~
#7楼
回复
引用
查看
2007-06-13 12:02
by
Cat Chen
好像这种情况下应该用SqlDataSource而非ObjectDataSource啊。ObjectDataSource是用于已经经过业务逻辑层封装的对象的,也就是说在业务逻辑层封装出分页接口就行了,我并不需要管背后的数据访问层用关系型数据库还是XML。然而你这篇文章的讨论重点是SQL,所以应该用SqlDataSource才对啊。
#8楼
回复
引用
2007-06-13 14:16
by
4x4y[未注册用户]
其实直接用DataReader分即省事又方便
搞笑太搞笑了,DataReader里面的数据哪里来的,是从数据库读取填充进来的,这里的分页就是就是只返回特定的数据库记录条数。不过这篇文章标题严重误导,楼主的意思其实就是从数据库中按需读取所需记录,和上面的ObjectDataSource压根没有关系,至于读取出来了你用DataReader用什么都成。
#9楼
[
楼主
]
回复
引用
查看
2007-06-13 15:41
by
漂泊雪狼
这篇文章是《用ObjectDataSource实现自定义分页的心得总结》的后继篇,
在
上篇
中我提到用ObjectDataSource分页的好处,但是在项目应用中我发现上篇中的分页存储过程效率可以继续提高和优化,于是写了这篇!
注册用户登录后才能发表评论,请
登录
或
注册
,
返回博客园首页
。
首页
博问
闪存
新闻
园子
招聘
知识库
最新IT新闻
:
·
春节后礼品回收iPhone成新宠燕窝被冷落
·
分析称苹果近1000亿现金储备最佳用途是派息
·
扎克伯格11件蠢事:曾同意将Facebook卖给雅虎
·
最想要的Entity Framework功能
·
专访Jeffrey Richter:Windows 8是微软的重中之重
»
更多新闻...
最新知识库文章
:
·
高级编程语言的发展历程
·
如何学习一门新的编程语言?
·
学习不同编程语言的重要性
·
为什么我喜欢富于表达性的编程语言
·
计算机专业的女生为什么要学编程
»
更多知识库文章...
China-pub 2011秋季教材巡展
China-Pub 计算机绝版图书按需印刷服务
Powered by:
博客园
Copyright © 漂泊雪狼
导航
博客园
首页
新随笔
联系
订阅
管理
公告
给我留言:
MSN:
E-Mail:
您是第 位访客
访问统计:
昵称:
漂泊雪狼
园龄:
5年10个月
粉丝:
2
关注:
0
<
2007年6月
>
日
一
二
三
四
五
六
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
搜索
常用链接
我的随笔
我的评论
我的参与
最新评论
我的标签
最新随笔
1. Java GUID Timestamp
2. Java sqlDate Date 转换示例
3. ExtJS中grid的JsonStore、Ext.PagingToolbar带条件查询问题
4. ExtJS 中Grid使用SimpleStore、多选框的方法
5. ExtJS Window 最小化的一种方法
6. Oracle 10g 行列转换(从SQL Server 2000迁移)
7. SQL Server 字段拆分的小技巧
8. CodeSmith Professional 5.0破解下载地址 注册机 keygen
9. Apache log4net与EntLib Logging Application Block使用心得
10. 用Codesmith写的一个的从SQL Server向Oracle导数据的模板
我的标签
SQL Server
(2)
Oracle
(1)
随笔分类
(54)
Ajax(12)
ASP.NET(16)
DataBase Others(7)
EXTJS(3)
Microsoft Visual SourceSafe(1)
Oracle(9)
SQL Server(6)
VB Script
随笔档案
(51)
2010年11月 (2)
2009年11月 (3)
2009年5月 (1)
2009年4月 (1)
2008年9月 (2)
2008年8月 (1)
2008年1月 (1)
2007年12月 (2)
2007年11月 (1)
2007年10月 (1)
2007年9月 (1)
2007年6月 (1)
2007年4月 (3)
2007年3月 (3)
2007年1月 (2)
2006年12月 (1)
2006年11月 (4)
2006年10月 (1)
2006年8月 (1)
2006年7月 (5)
2006年6月 (2)
2006年4月 (4)
2006年3月 (8)
文章分类
(11)
Excel操作(3)
脚本知识(2)
其他(4)
数据库(2)
文章档案
(10)
2006年12月 (1)
2006年11月 (1)
2006年9月 (1)
2006年8月 (1)
2006年7月 (1)
2006年6月 (3)
2006年3月 (2)
相册
个人相册
常用链接
24小时学习网
dotnettiers
Enterprise Library 3.1中文文档
Google
谷歌搜索
Microsoft patterns & practices
MS Enterprise Library
百度搜索
百度搜索
层叠样式表手册
动态网站制作指南
就爱E书网
无忧视窗
资源中国
个人链接
MSN共享空间
网易相册
友情博客
newwind
VirtualMJ
中文爱百科
可信赖的中文百科全书
积分与排名
积分 - 107561
排名 - 939
最新评论
阅读排行榜
评论排行榜
推荐排行榜