CREATE procedure pagination1 (@pagesize int, --页面大小,如每页存储20条记录 @pageindex int --当前页码) as set nocount on
begin
declare @indextable table(id int identity(1,1),nid int) --定义表变量 declare @PageLowerBound int --定义此页的底码 declare @PageUpperBound int --定义此页的顶码
set @PageLowerBound=(@pageindex-1)*@pagesize set @PageUpperBound=@PageLowerBound+@pagesize set rowcount @PageUpperBound insert into @indextable(nid) select gid from TGongwen where fariqi >dateadd(day,-365,getdate()) order by fariqi desc select O.gid,O.mid,O.title,O.fadanwei,O.fariqi from TGongwen O,@indextable t where O.gid=t.nid and t.id>@PageLowerBound and t.id<=@PageUpperBound order by t.id
select top 页大小 * from table1 where id> (select max (id) from (select top ((页码-1)*页大小) id from table1 order by id) as T) order by id
文章中的点评:
我们知道,几乎任何字段,我们都可以通过max(字段)或min(字段)来提取某个字段中的最大或最小值,所以如果这个字段不重复,那么就可以利用这些不重复的字段的max或min作为分水岭,使其成为分页算法中分开每页的参照物。在这里,我们可以用操作符“>”或“<”号来完成这个使命,使查询语句符合SARG形式。如: Select top 10 * from table1 where id>200
这个就高高效了一点。但是不清楚 max的工作原理,不知道它的性能如何。
心得:
1、追求高效的翻页算法 —— 定位法。
declare @pageSize int --返回一页的记录数 declare @CurPage int --页号(第几页)0:第一页;-1最后一页。
declare @Count int declare @id int
set @pageSize=10 set @CurPage =1
--定位 if @CurPage = -1 begin --最后一页 set rowcount @pageSize select @id=newsID from newsTemp order by newsID end
if @CurPage > 0 begin set @Count = @pageSize * (@CurPage -1) + 1 set rowcount @Count select @id=newsID from newsTemp order by newsID desc end
--返回记录 set rowcount @pageSize select * from newsTemp where newsID <=@id order by newsID desc
set rowcount 0
思路:就是上面的算法的延续,就是说呢避免使用 not in 和 max 的方法。也就是这个思路:Select top 10 * from table1 where id>200,定位 —— 就是说要找到“临界点”,分页的临界点。找到了之后剩下的事情就好办了。
缺点:单字段排序、排序字段的值不能重复(不是绝对不能重复,可以有少量的重复)。
2、通用法 —— 颠颠倒倒法
有的时候“定位法”的缺点是不可以接受的,但是没有关系,可以用这个的。
select * from table where id in ( select top 10 ID from ( select top 20 ID,addedDate from table order by addedDate desc ) as aa order by addedDate ) order by addedDate desc