[转]SQL Server 存储过程的分页方案比拼

本文探讨了SQL Server中三种不同的分页方法:使用Not In和SELECT TOP,利用ID大于某个值和SELECT TOP,以及利用游标存储过程进行分页。通过对这些方法的效率对比,得出在实际应用中应根据具体情况选择最优方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
  1None.gifSQL Server 存储过程的分页,这个问题已经讨论过几年了,很多朋友在问我,所以在此发表一下我的观点
  2None.gif建立表:
  3None.gif
  4None.gifCREATE TABLE [TestTable] (
  5None.gif [ID] [int] IDENTITY (11NOT NULL ,
  6None.gif [FirstName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
  7None.gif [LastName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
  8None.gif [Country] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
  9None.gif [Note] [nvarchar] (2000) COLLATE Chinese_PRC_CI_AS NULL 
 10None.gifON [PRIMARY]
 11None.gif GO
 12None.gif 
 13None.gif  
 14None.gif 插入数据:(2万条,用更多的数据测试会明显一些)
 15None.gif SET IDENTITY_INSERT TestTable ON
 16None.gif 
 17None.gif declare @i int
 18None.gif set @i=1
 19None.gif while @i<=20000
 20None.gif begin
 21None.gif     insert into TestTable([id], FirstName, LastName, Country,Note) values(@i'FirstName_XXX','LastName_XXX','Country_XXX','Note_XXX')
 22None.gif     set @i=@i+1
 23None.gif end
 24None.gif 
 25None.gif SET IDENTITY_INSERT TestTable OFF
 26None.gif 
 27None.gif  
 28None.gif 
 29None.gif -------------------------------------
 30None.gif 
 31None.gif 分页方案一:(利用Not In和SELECT TOP分页)
 32None.gif 语句形式:
 33None.gif SELECT TOP 10 *
 34None.gif FROM TestTable
 35None.gif WHERE (ID NOT IN
 36None.gif           (SELECT TOP 20 id
 37None.gif          FROM TestTable
 38None.gif          ORDER BY id))
 39None.gif ORDER BY ID
 40None.gif 
 41None.gif 
 42None.gif SELECT TOP 页大小 *
 43None.gif FROM TestTable
 44None.gif WHERE (ID NOT IN
 45None.gif           (SELECT TOP 页大小*页数 id
 46None.gif          FROM 表
 47None.gif          ORDER BY id))
 48None.gif ORDER BY ID
 49None.gif 
 50None.gif -------------------------------------
 51None.gif 
 52None.gif 分页方案二:(利用ID大于多少和SELECT TOP分页)
 53None.gif 语句形式:
 54None.gif SELECT TOP 10 *
 55None.gif FROM TestTable
 56None.gif WHERE (ID >
 57None.gif           (SELECT MAX(id)
 58None.gif          FROM (SELECT TOP 20 id
 59None.gif                  FROM TestTable
 60None.gif                  ORDER BY id) AS T))
 61None.gif ORDER BY ID
 62None.gif 
 63None.gif 
 64None.gif SELECT TOP 页大小 *
 65None.gif FROM TestTable
 66None.gif WHERE (ID >
 67None.gif           (SELECT MAX(id)
 68None.gif          FROM (SELECT TOP 页大小*页数 id
 69None.gif                  FROM 表
 70None.gif                  ORDER BY id) AS T))
 71None.gif ORDER BY ID
 72None.gif 
 73None.gif 
 74None.gif -------------------------------------
 75None.gif 
 76None.gif 分页方案三:(利用SQL的游标存储过程分页)
 77None.gif create  procedure XiaoZhengGe
 78None.gif @sqlstr nvarchar(4000), --查询字符串
 79None.gif @currentpage int--第N页
 80None.gif @pagesize int --每页行数
 81None.gif as
 82None.gif set nocount on
 83None.gif declare @P1 int--P1是游标的id
 84None.gif  @rowcount int
 85None.gif exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output
 86None.gif select ceiling(1.0*@rowcount/@pagesizeas 总页数--,@rowcount as 总行数,@currentpage as 当前页 
 87None.gif set @currentpage=(@currentpage-1)*@pagesize+1
 88None.gif exec sp_cursorfetch @P1,16,@currentpage,@pagesize 
 89None.gif exec sp_cursorclose @P1
 90None.gif set nocount off
 91None.gif 
 92None.gif 其它的方案:如果没有主键,可以用临时表,也可以用方案三做,但是效率会低。
 93None.gif 建议优化的时候,加上主键和索引,查询效率会提高。
 94None.gif 
 95None.gif 通过SQL 查询分析器,显示比较:我的结论是:
 96None.gif 分页方案二:(利用ID大于多少和SELECT TOP分页)效率最高,需要拼接SQL语句
 97None.gif 分页方案一:(利用Not In和SELECT TOP分页)   效率次之,需要拼接SQL语句
 98None.gif 分页方案三:(利用SQL的游标存储过程分页)    效率最差,但是最为通用
 99None.gif
100None.gif在实际情况中,要具体分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值