惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
博客园 - 司徒正美
罗磊的独立博客
D
Docker
Last Week in AI
Last Week in AI
爱范儿
爱范儿
M
MIT News - Artificial intelligence
V
V2EX
Google DeepMind News
Google DeepMind News
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Security Blog
Microsoft Security Blog
T
Tailwind CSS Blog
MyScale Blog
MyScale Blog
V
Visual Studio Blog
博客园 - 叶小钗
B
Blog RSS Feed
A
About on SuperTechFans
F
Fortinet All Blogs
T
The Blog of Author Tim Ferriss
Martin Fowler
Martin Fowler
P
Proofpoint News Feed

博客园 - TomSun

sql语句优化 页面生存周期 利用鼠标中键缩放图片 - TomSun - 博客园 不间断连续图片滚动效果的制作方法 - TomSun - 博客园 IE问题解决方法汇总 Calendar的相关问题. 无法打开注册表关键字错误----修改方法 N级无刷新连动菜单 - TomSun - 博客园 JScript中正则表达函数的说明与应用 正则表达式语法 ASP生成柱型体,折线图,饼图源代码 - TomSun - 博客园 ASP必读[常见问题集] 常用SQL语句(不断更新) Javascript里类的思想(zz) - TomSun - 博客园 JS写的Cookie类 ASP调用系统ping命令 c#.net常用的小函数和方法集 XMLHTTP---介绍 ASP.net 验证码(C#)
SQL Server 存储过程的分页
TomSun · 2005-09-26 · via 博客园 - TomSun

建立表: 

CREATE TABLE [TestTable] ( 
[ID] [int] IDENTITY (11NOT NULL , 
[FirstName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL , 
[LastName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL , 
[Country] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL , 
[Note] [nvarchar] (2000) COLLATE Chinese_PRC_CI_AS NULL 
ON [PRIMARY] 
GO 



插入数据:(2万条,用更多的数据测试会明显一些) 
SET IDENTITY_INSERT TestTable ON 

declare @i int 
set @i=1 
while @i<=20000 
begin 
insert into TestTable([id], FirstName, LastName, Country,Note) values(@i'FirstName_XXX','LastName_XXX','Country_XXX','Note_XXX'
set @i=@i+1 
end 

SET IDENTITY_INSERT TestTable OFF 



------------------------------------- 

分页方案一:(利用Not In和SELECT TOP分页) 
语句形式: 
SELECT TOP 10 * 
FROM TestTable 
WHERE (ID NOT IN 
(
SELECT TOP 20 id 
FROM TestTable 
ORDER BY id)) 
ORDER BY ID 


SELECT TOP 页大小 * 
FROM TestTable 
WHERE (ID NOT IN 
(
SELECT TOP 页大小*页数 id 
FROM 表 
ORDER BY id)) 
ORDER BY ID 

------------------------------------- 

分页方案二:(利用ID大于多少和SELECT TOP分页) 
语句形式: 
SELECT TOP 10 * 
FROM TestTable 
WHERE (ID > 
(
SELECT MAX(id) 
FROM (SELECT TOP 20 id 
FROM TestTable 
ORDER BY id) AS T)) 
ORDER BY ID 


SELECT TOP 页大小 * 
FROM TestTable 
WHERE (ID > 
(
SELECT MAX(id) 
FROM (SELECT TOP 页大小*页数 id 
FROM 表 
ORDER BY id) AS T)) 
ORDER BY ID 


------------------------------------- 

分页方案三:(利用SQL的游标存储过程分页) 
create procedure XiaoZhengGe 
@sqlstr nvarchar(4000), --查询字符串 
@currentpage int--第N页 
@pagesize int --每页行数 
as 
set nocount on 
declare @P1 int--P1是游标的id 
@rowcount int 
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output 
select ceiling(1.0*@rowcount/@pagesizeas 总页数--,@rowcount as 总行数,@currentpage as 当前页 
set @currentpage=(@currentpage-1)*@pagesize+1 
exec sp_cursorfetch @P1,16,@currentpage,@pagesize 
exec sp_cursorclose @P1 
set nocount off 

其它的方案:如果没有主键,可以用临时表,也可以用方案三做,但是效率会低。 
建议优化的时候,加上主键和索引,查询效率会提高。 

通过SQL 查询分析器,显示比较:我的结论是: 
分页方案二:(利用ID大于多少和SELECT TOP分页)效率最高,需要拼接SQL语句 
分页方案一:(利用Not In和SELECT TOP分页) 效率次之,需要拼接SQL语句 
分页方案三:(利用SQL的游标存储过程分页) 效率最差,但是最为通用 

在实际情况中,要具体分析。