读书人

分页控件之分页算法 for SQL Ser

发布时间: 2012-01-01 23:10:55 作者: rapoo

分页控件之分页算法 —— for SQL Server 版。百万级的数据只需要15毫秒到900毫秒

下载分页控件(包括源码和演示)

分页控件使用方法

关于分页的误区
误区1:分页的时候,只有使用存储过程,效率才高。
误区2:忽略了索引的作用。

上两篇好像介绍的不太详细,这里详细说明一下分页控件里使用的分页算法,也就是SQL语句。

分页一般分为四种情况

1、单字段排序,排序字段没有重复值。
2、单字段排序,排序字段有重复值。
3、多字段排序,最后一个排序字段没有重复值。
4、多字段排序,最后一个排序字段有重复值。

其中第2、4 情况都可以再加一个排序字段(比如说主键),就可以转换成第三种情况。

所以分页针对1、3两种情况设置了两种分页算法。

1、单字段排序,排序字段没有重复值。

公式:

1declare @col int
2
3select top {PageSize * (PageIndex-1)+1} @col = [排序字段]
4from [表名|视图名]
5[ where 查询条件 ]
6order by [排序字段] asc|desc
7
8select top PageSize 需要显示的字段
9from [表名|视图名]
10where [排序字段] >= @col
11[ and 查询条件 ]
12order by [排序字段] asc|desc
以NorthWind 数据库里的 Products 表为例,假设一页显示10条数据,CategoryID = 3 为查询条件,按照ProductID 倒序,如果想显示第二页的数据,那么SQL语句就是
declare @col int

select top 11 @col = ProductID from Products where CategoryID = 3 order by ProductID desc

select top 10 * from Products where ProductID >= @col and CategoryID = 3 order by ProductID desc
说明:
第一行的定义,要根据字段类型来修改,看是比较麻烦,但是这个麻烦交给分页控件就可以了,使用者,只要设置分页控件的属性就可以了。
第五行和第十一行,如果需要加查询条件的话就可以在这里添加。

第三行是一个“定位”,这个可以算是SQL Server 所特有的吧,也是SQL Server 很宽容的地方。以Products 表的例子,执行完第一条select 语句之后, @col 里面记录的是 在CategoryID = 3 的记录里面,按照ProductID 倒序,排行在11位的记录的值。

第一个select 语句定位以后,第二个select 语句就可以根据这个“位置”继续向下查找数据了。

虽然例子里面使用了ProductID(主键)来排序,但是并不是说这个算法只能用主键来排序,哪个字段都可以,但是要符合第一种情况,就是“只有一个排序字段,且排序字段里的记录没有重复值”!


3、多字段排序,最后一个排序字段没有重复值。

如果 Products 表想要用 UnitPrice 字段来排序怎么办呢?上面的算法是不适合的,我们需要使用另一种算法,这个和颠颠倒倒法有些类似,但是我做了一些优化。

公式:
select [需要显示的字段] from [表名|视图名] where [主键字段] in

( select top PageSize [主键字段] from
(select top {PageSize * PageIndex} [主键字段] , [排序字段] from --有几个排序字段就写几个字段

[表名|视图名]
[ where 查询条件 ]
order by

[排序字段1] asc|desc ,
[排序字段2] desc|asc,

[主键字段] asc|desc
) as aa
order by
[排序字段1] desc|asc, --如果上面是倒序,那么这里就是正序,下同
[排序字段2] asc|desc ,

[主键字段] desc|asc

)

order by
[排序字段1] asc|desc, --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。
[排序字段2] desc|asc,

[主键字段] asc|desc
以NorthWind 数据库里的 Products 表为例,假设一页显示10条数据,CategoryID = 3 为查询条件,按照UnitPrice 倒序,由于UnitPrice 字段可能有重复值,所以加上一个排序字段——ProductID ,即按照 UnitPrice desc,ProductID 来排序。 如果想显示第二页的数据,那么SQL语句就是
select * from Products where ProductID in
( select top 10 ProductID from
(select top 20 ProductID , UnitPrice from
Products
where CategoryID = 3
order by
UnitPrice desc ,
ProductID
) as aa
order by
UnitPrice asc, --如果上面是倒序,那么这里就是正序,下同
ProductID desc
)
order by
UnitPrice desc, --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。
ProductID
说明:
1、这里查询条件加一次就可以了。
2、是不是看 asc|desc 倒来倒去的有点晕,恩,这就对了,颠颠倒倒嘛。
3、最主要的就是第三个select 语句,他要取从第一条数据到要显示的页的数据,可见越是后面的记录,top n 就会越大,所以这里提取的数据就要做一个精简,只写排序需要的字段(主键字段和排序字段)。


4、第二个select 语句是去掉前面不需要的页里的数据,只保留要显示的页号里的数据。
5、第一个select 语句,用主键字段 in () 的方式提取其他需要的字段。
6、这种分页算法有一个小的bug,就是显示最后一页数据的时候,会多出来几条记录,不过这个bug已经在分页控件里面修正了,最后一页的分页算法,采用特殊的select语句。
7、效率,设置好索引,效率是没有问题的,上一篇随笔已经测试过了。
8、这种算法有一个“侵入性”,就是要求表必须有主键,而且不能是联合主键,引为要用 in 的方式查询数据。但是并没有要求主键自身必须能够排序。

测试效果
记录数:2523136条。
一页显示5条记录。


//分页算法1 单字段排序,且排序字段是聚集索引。
//1000 页以内 15毫秒
//10000页以内 30毫秒
//50000页以内 100多毫秒
//100000页以内 200多毫秒
//最后几页 第一次跳转到 4秒多
//最后几页 连续向前翻页 1秒156毫秒

//页号大范围跳转的时候需要的时间比较长,但是也小于1秒,同时SQL Server 占用的内存有所增加 120M。最后几页时达到320M

===================================================================
以下是多排序字段的分页情况,排序字段是 UnitPrice,ProductID

//分页算法2 无索引 首页 8秒187毫秒 。
//10 页以内 2秒812毫秒
//速度太慢下面的就不测试了

//分页2 非聚集索引 UnitPrice 首页 468毫秒
//10 页以内 2秒671毫秒
//速度太慢下面的就不测试了


//分页算法2 非聚集索引 UnitPrice,ProductID 首页 500毫秒
//10 页以内 2秒796毫秒
//100页以内 4秒796毫秒
//速度太慢下面的就不测试了


//分页算法2 非聚集索引 UnitPrice,ProductID desc 首页 500毫秒
//10 页以内 0-15毫秒
//100页以内 15-46毫秒
//1000页以内 31-62毫秒
//10000页以内 100毫秒左右
//50000页以内 400-500毫秒
//100000页以内 900毫秒左右
//最后几页 第一次跳转到 4秒421毫秒
//最后几页 连续向前翻页 4秒375毫秒

//页号大范围跳转的时候需要的时间比较长,但是也小于1秒,
//这回SQL Server 占用的内存增加幅度不大 120M左右



[解决办法]
学习
[解决办法]
还没见过比吴旗娃那个更有效的
[解决办法]
学习!
[解决办法]
不错,谢谢分享
[解决办法]
谢谢LZ
[解决办法]
顶!做的不错!
[解决办法]
顶~
[解决办法]
留个记号,明天研究
[解决办法]
xue xi@
[解决办法]
学习
[解决办法]
谢谢分享
[解决办法]
mark
[解决办法]
mark
[解决办法]
学习
[解决办法]
顶一个,学习
[解决办法]
靠,LZ的不错,深入学习中...
[解决办法]
mark!
[解决办法]
学习
[解决办法]
xuexi
[解决办法]
谢谢分享 学习了..


[解决办法]
学习
[解决办法]
好 收藏
[解决办法]

[解决办法]
谢谢,收藏了
[解决办法]
good
[解决办法]
收藏了好好看下!
[解决办法]
不错,学习
[解决办法]
mark 学习之
[解决办法]

探讨
还没见过比吴旗娃那个更有效的

[解决办法]
mark.
[解决办法]
mark
[解决办法]
星星也不杂的哈。。。。晚上到博客公布我写的。。。哎。。
[解决办法]
收藏
[解决办法]
还是觉得吴旗娃那个效率比较高
[解决办法]
好东东就要顶
[解决办法]
呵呵..刚刚把我写的存储过程写在博客里了..欢迎大家去看看
[解决办法]
学习一下
[解决办法]
mark
[解决办法]
学习!
[解决办法]
误区1:分页的时候,只有使用存储过程,效率才高。
----------------------------------------------
这句楼主指点指点,不用过程用什么效率还好?看到回帖请指点一下
[解决办法]
探讨
误区1:分页的时候,只有使用存储过程,效率才高。
----------------------------------------------
这句楼主指点指点,不用过程用什么效率还好?看到回帖请指点一下

[解决办法]
顶下!
[解决办法]
mark
[解决办法]
up
[解决办法]
学习
厉害
[解决办法]
还习试,相信楼主.过会好好试一下,一定要掌握了.
[解决办法]
先收藏,慢慢研究
[解决办法]
自己写的分页程序,2515232条数据,前面一万页需时在0:00:01左右,一万页以上到最后一页在0:00:02左右(查询分析器的统计时间,每页有一百条数据)
[解决办法]
确切的说,前面一万页显示的执行时间是0:00:00,也就是不超过0:00:01,后面的显示的执行时间为0:00:01,也就是不会超过0:00:02

第一页直接跳转到最后一页,所需时间不超过0:00:02
[解决办法]
学习
[解决办法]


mark
[解决办法]
端午节快乐
辛苦。。
[解决办法]
看看
[解决办法]
100W级数据 豪秒级查询数据?
我不相信.
请问下你这 100W的数据,有多少M

我以前与到过一个项目,20W数据.
数据大小是30M左右,
不使用索引的话 查询速度在4-7秒间.
我的方法.http://www.flywud.com/index.php/200806/29.htm
参照我的方法,还能让你的平均速度减少一倍.
但是 1秒的都不要 我不相信.
如果是建立索引 的话 就不同了 我还没正式测试过.
[解决办法]
up
[解决办法]
极力推荐 动易 管方的sql2000 分也,可以对任意字段排序,
N多分页存储过程,我就喜欢她!!!!!!1
http://www.cnblogs.com/wdfrog/archive/2008/02/02/1062263.html
[解决办法]
貌似很强大.顶了。
[解决办法]

探讨
100W级数据 豪秒级查询数据?
我不相信.
请问下你这 100W的数据,有多少M

我以前与到过一个项目,20W数据.
数据大小是30M左右,
不使用索引的话 查询速度在4-7秒间.
我的方法.http://www.flywud.com/index.php/200806/29.htm
参照我的方法,还能让你的平均速度减少一倍.
但是 1秒的都不要 我不相信.
如果是建立索引 的话 就不同了 我还没正式测试过.

[解决办法]
探讨
确切的说,前面一万页显示的执行时间是0:00:00,也就是不超过0:00:01,后面的显示的执行时间为0:00:01,也就是不会超过0:00:02

第一页直接跳转到最后一页,所需时间不超过0:00:02

[解决办法]
学习了
[解决办法]
这个应该好好研究.
[解决办法]
这个要慢慢消化,谢谢楼主。
[解决办法]
学习了
[解决办法]
学习,谢谢了
[解决办法]
jf
[解决办法]
吴的分页是不错
还有分页控件
不过我总发现
吴的分页
没有阿里巴巴搜索出来的分页快
还有象baidu,google这样的分页是怎么做出来的
baidu,google数据应该不少吧
可是显示数据快
分页也快
不能用秒来计算
只能是毫秒
[解决办法]
ctrl+c ctrl+v 去试试
[解决办法]
学习!
[解决办法]
~~~~~~~~~
[解决办法]
很好很强大
[解决办法]
学习了
[解决办法]
支持下~~
[解决办法]
都是高人啊~~~
[解决办法]
look look,mark!
[解决办法]
mark
[解决办法]
不错,支持一下
[解决办法]
哦,不错,支持一下

辛苦
------解决方案--------------------


收藏
[解决办法]
先,收藏哈
[解决办法]
真是不错!
[解决办法]
学习呀~~~
[解决办法]
研究一下,原来有个分页程序,不知道搞到哪去了
[解决办法]
不错!谢谢啦!
[解决办法]
晕,现在都是玩性能了,我还在为实现问题发愁,层次不同哦
[解决办法]
keywords=sql优化,分页算法
//mark
[解决办法]

探讨
顶~

[解决办法]
探讨
吴的分页是不错
还有分页控件
不过我总发现
吴的分页
没有阿里巴巴搜索出来的分页快
还有象baidu,google这样的分页是怎么做出来的
baidu,google数据应该不少吧
可是显示数据快
分页也快
不能用秒来计算
只能是毫秒

[解决办法]
mark

读书人网 >asp.net

热点推荐