SQL分页查询优化

基于如下基础分页方案

select top 页大小 *
from table1
where id>
(select max (id) from
(select top ((页码-1)*页大小) id from table1 order by id) as T --瓶颈
)
order by id

随着分页数的上升,尽管只选取了ID列,但量上仍然很惊人,关键就是top得太多>:

 

改进点也就出在这里:

1、一分为二

因为 纪录中点 = 总纪录数/2,如果超过纪录中点,改变一下order的顺序(降序<->升序),



由X = ((页码-1)*页大小),更改相应的top数(总纪录-X)

--降序排列
SELECT TOP 页大小 * FROM 表 WHERE ID <
(SELECT MIN(ID)
FROM
(SELECT TOP X ID FROM 表 ORDER BY ID DESC) AS tblTmp)
ORDER BY ID DESC

=>

--升序排列
SELECT TOP 页大小 * FROM 表 WHERE ID >
(SELECT MAX(ID)
FROM
(SELECT TOP 总记录-X ID FROM 表 ORDER BY ID ASC) AS tblTmp)
ORDER BY ID ASC


以上只是分段纪录集的特例,我们完全可以通过SQL计算出1/4,1/8,1/16,1/32……等不同情况下的纪录临界,进一步缩小结果集。

2、top 10

尽管一个N大的表可以分为N/pagesize多的页,不过现实情况是,很少有人会一页一页的翻到10000页,统计概率告诉我们,一个人的翻页的耐心很少有大于10的,80%的翻页又集中在前20%,也就是前两页!

2.1 预载
我们可以不用吹灰之力预先计算出top 10页的临界ID:

select max (id) from
(select top ((页码-1)*页大小) id from table1 order by id) as T

然后放入[1][2][3][……]这样的分页链接中(形如showpage.asp?id=1000),用

select top 页大小 *
from table1
where id>QueryString(ID)

轻松实现分页。

2.2 setp by setp
更幸运的是,绝大多数情况下,人们是一页接一页的翻阅,于是,我们还有针对这90%+情况的更优的解决方案。
首先打开第一页,我们得到第一页最后一条纪录的ID,这就是第二页分页的初始ID!
如果打开第N页,那么第一条记录的ID就是MAX(N-1页纪录ID)+1,最后一条纪录就是MIN(N+1页纪录ID)-1,用所得到的ID更改临近页面的URL;

升序排列:

--N-1页

SELECT TOP 页大小 *
 FROM table1
 WHERE ID < MIN_ID ORDER ORDER BY ID ASC

--N+1页

SELECT TOP 页大小 *
 FROM table1
 WHERE ID > MAX_ID ORDER ORDER BY ID ASC

降序排列:

--N-1页

SELECT TOP 页大小 *
 FROM table1
 WHERE ID > MAX_ID ORDER ORDER BY ID DESC

--N+1页

SELECT TOP 页大小 *
 FROM table1
 WHERE ID < MIN_ID ORDER ORDER BY ID DESC

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值