(转)2个高效存储过程分页及对比

随笔- 151 文章- 9 评论- 11

2个高效存储过程分页及对比

        前两天在网上发现了一条存储过程分页的例子,是利用mssql2005中新添加的函数ROW_NUMBER()来实现的,于是修改了下并且和以前用游标的分页函数进行了以下对比,下面分别将两个存储过程写下来。
        1、使用ROW_NUMBER()的方法来实现:

1
2
3
4 /**/ /*-----------------------------------------------------------------
5模块:分页查询存储过程
6
7
8    2008/03/10    创建    郑玉路
9
10-------------------------------------------------------------------*/

11 CREATE PROCEDURE PAGINATION_FUNCTION
12 (
13     @strTable VARCHAR ( 1500 ) = '' ,            -- 表名-FROM以后的字符串 例:(单表)ORDERS\(多表)ORDERS LEFT JION CUSTOMER ON ORDERS.CUSTOMERID = ORDERS.CUSTOMERID
14     @strReturn VARCHAR ( 1500 ) = ' * ' ,            -- 需要返回的列 例:ORDERID,CUSTOMERID
15     @strOrderBy VARCHAR ( 1000 ) = '' ,            -- 排序的字段名 orderdate asc,shippeddate desc
16     @PageSize INT = 10 ,                     -- 一页的记录数大小
17     @PageIndex   INT = 1 ,                    -- 当前页页码
18     @doCount   INT = 0 output                -- 返回记录总数
19 )
20 AS
21
22
23     -- 获取总记录数
24     DECLARE @tpSEL NVARCHAR ( 4000 )            -- 获取总记录数临时语句
25     SET @tpSEL = N ' SELECT @doCount=COUNT(*)  FROM ' + rtrim ( @strTable )
26     EXEC sp_executesql @tpSEL , N ' @doCount int output ' , @doCount output
27     -- 获取总记录数
28    
29     DECLARE @tpSEL2 VARCHAR ( 8000 )
30     DECLARE @RowStart INT                     -- 开始行标记
31     DECLARE @RowEnd INT                         -- 结束行标记
32    
33     SET @RowStart = @PageSize * @PageIndex - @PageSize + 1
34     SET @RowEnd = @PageSize * @PageIndex
35    
36     SET @tpSEL2 = ' SELECT * FROM ( SELECT ROW_NUMBER() OVER(ORDER BY ' + rtrim ( @strOrderBy )
37                   + ' ) AS ROWS, ' + rtrim ( @strReturn )
38                   + ' FROM ' + rtrim ( @strTable )
39                   + ' ) AS TEMP WHERE ROWS BETWEEN ' + rtrim ( @RowStart )
40                   + ' AND ' + rtrim ( @RowEnd )
41                  
42     EXEC ( @tpSEL2 )
43
44     RETURN
45
46
47

        2、游标方式:

CREATE procedure p_splitpage
   
@sql nvarchar ( 4000 ), -- 要执行的sql语句
    @page int = 1 , -- 要显示的页码
    @pageSize int , -- 每页的大小
    @pageCount int = 0 out, -- 总页数
    @recordCount int = 0 out, -- 总记录数
    @SearchTime int = 0 out     -- 计算耗时
as
   
declare @usetime datetime
   
set @usetime = getdate ()
   
set nocount on
   
declare @p1 int
   
exec sp_cursoropen @p1     

output,
@sql , @scrollopt = 1 , @ccopt = 1 , @rowcount = @pagecount output
   
set @recordCount = @pageCount
   
select @pagecount = ceiling ( 1.0 * @pagecount / @pagesize )
            ,
@page = ( @page - 1 ) * @pagesize + 1
   
exec sp_cursorfetch @p1 , 16 , @page , @pagesize
   
exec sp_cursorclose @p1
   
set   @SearchTime = datediff (ms, @usetime , getdate ())
   
print @SearchTime

        然后分别对15000条的数据进行测试,发现2个存储过程的耗时几乎一样,第一种方法的耗时相对要比第二种稍微快几毫秒,而且不管是查询第几页的数据基本上比较稳定,只是相对的使用起来没有第二种方法方便,但是对于百万条以上的数据的效果如何确没有进行测试,具体哪种方法更好还不得而知,而且哪位朋友如果方便的话可以帮忙修改下相应的不足之处,同时还有一个比较头痛的问题,就是再使用EXEC SP_EXECUTESQL @TPSEL...这个方法的时候,变量@TPSEL不能声明为varchar类型,只能为nvarchar,这个问题具体是因为什么我还没有查到原因!


分类: ASP.NET, 数据库
标签: 存储过程, 分页
0
0
    (请您对文章做出评价)   
» 博主后一篇: [导入]两个粒度看Asp.net生命周期


posted @ 2008-03-07 17:47 潜水员 阅读(1082) 评论( 2编辑 收藏

#1楼 2008-03-10 21:29 | Heclei
都不错,我用第二种!
#2楼 1182150 2008/5/4 18:28:00 2008-05-04 18:28 | YY_GG[未注册用户]
你好啊 我是个菜鸟 能否给个使用实例学习一下最好带个查询条件,不知道能否发到我的邮箱里呀 谢谢啦

转载于:https://www.cnblogs.com/wangyt223/archive/2012/10/09/2716067.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值