金色海洋工作室

——自然框架,自然而然,快速开发、快速修改!

 

分页解决方案 之 分页算法——Pager_SQL的思路和使用方法


      分页算法(也就是分页读取数据的时候使用的select 语句)面临两大难题:一个是不同的数据库使用的分页算法是不一样的(比如SQL Server 2000可以使用Max、表变量、颠倒Top,SQL Server 2005可以使用Row_Number,MySql可以使用limit ,Orcale可以使用ROWNUM等);另一个是,不同的分页需求,可以采用的分页算法也是不一样的(比如单字段排序和多字段排序)。那么我们应该如何来选择呢?

      好多人都想找到一种即通用,效率又高的分页算法,那么能不能找到呢?我是找了很久都没有找到,看了许多人写得文章,我也没有发现(请不要和我说那个什么表变量的)。既然找不到,那就要做多手准备了。

      我的想法就是准备多种分页算法的“模板”,然后根据数据库的种类,根据分页需求来选择到底是用哪一种分页算法。就是说使用哪一种是不固定的,依据条件而定。那么如何来实现呢?我做了一个类库来做这个事情,请看下面的图示:
 
 

 

 

 


      Pager_SQL原来是QuickPager分页控件的一部分,现在独立出来可以单独使用。

      Pager_SQL就好像一个加工厂,给他输入“原料”(表名、字段名、排序字段等),然后再选择“加工方式”(选择分页算法),最后我们就可以得到所需的“产品”(分页用的select 语句)了。

      因为不管是什么数据库(只要是关系型数据库),那么就会有表、字段、视图,要分页就要有排序字段等,所以呢这些原料都是固定的,变化的只是分页用的SQL语句,这个Pager_SQL就是“生产”各种SQL语句的工厂。这样不同的分页算法既可以适应不同的数据库,也可以使用不同的分页需求。

      Pager_SQL的原理很简单,就是拼接字符串(也就是拼接SQL语句),然后通过数据访问函数库(或者其他的help等)提交给数据库执行。采用了基类的方式,所以如果需要增加分页算法的话,那么只要继承这个基类写一个子类,如果有不同的地方,覆盖一下就可以了。下面是类图:

 

 

      说到这里,您可能会有两个疑问:1、拼接字符串的效率是不是会很慢?2、SQL语句和储存过程相比是不是很慢?两个“慢”加起来,是不是变成了“巨慢”。一开始我也是比较担心,但是用了五年多,也用100万条记录做过测试,效率还是很理想的。这两天我又详细的测试了一下,在测试的过程中也发现了不少细节问题,以前忽略的地方,由于测试的比较乱,所以我想整理一下然后再写出来。

 

使用方法:

 

//实例化
JYK.Controls.Pager.QuickPagerSQL PagerSQL = new QuickPagerSQL();

protected void Page_Load(object sender, EventArgs e)
        
{
            
//设置属性
            PagerSQL.TableName = "News_NewsInfo";          //表名或者视图名称
            PagerSQL.TableShowColumns = "*";               //需要显示的字段
            PagerSQL.TableIDColumn = "NewsID";             //主键名称,不支持复合主键
            PagerSQL.TableOrderByColumns = "NewsID";       //排序字段,根据分页算法而定,可以支持多个排序字段
            PagerSQL.TableQuery = "";                      //查询条件

            PagerSQL.PageSize 
= 4;                         //一页显示的记录数

            PagerSQL.PageCount 
= 100;
            PagerSQL.ComputePageCount(
100,4);

        }


        
测试拼接字符串的效率

 

 

源码下载:http://www.cnblogs.com/jyk/archive/2008/07/29/1255891.html

ps:下一篇里我会测试程序里面拼接字符串的时间、SQL Server2000分析、制作执行计划的时间,SQL语句和储存过程的对比,exe (@sql)和 exec sp_executesql @sql 的区别。

 

 

posted on 2009-05-15 07:03 金色海洋(jyk)阳光男孩 阅读(3907) 评论(23) 编辑 收藏

评论

#1楼 2009-05-15 07:30 关注网页游戏      

建议做成工具好了  回复 引用 查看   

#2楼[楼主] 2009-05-15 07:46 金色海洋(jyk)      

这是一个基本的用法,可以在许多的地方应用,代码生成器里面好像也可以用。

Pager_SQL就是要尽量的独立,让更多的地方可以使用。

我还想把参数化的SQL语句引用进来,能参数化的尽量参数化。

至于工具吗,我要写一个“项目的管理程序”,Pager_SQL会是里面的一个小部分。
 回复 引用 查看   

#3楼 2009-05-15 08:11 温景良(Jason)      

up  回复 引用 查看   

#4楼 2009-05-15 08:15 OK_008      

分页的原理是一样的,只是在实际的应用中,具体问题具体分析,写合适自己需求的方法。可以参考一篇《Custom Pagination in SQL Server 2005》:

http://www.sqlservercentral.com/articles/SQL+Server+2005/65256/
 回复 引用 查看   

#5楼[楼主] 2009-05-15 08:17 金色海洋(jyk)      

这个只是为了便于编写SQL语句,具体的分页算法,可以自己来修改。  回复 引用 查看   

#6楼 2009-05-15 08:59 minus[未注册用户]

这样的分页好像只支持单表查询,多表联合查询时会有问题  回复 引用   

#7楼 2009-05-15 09:01 海浪空间      

up
 回复 引用 查看   

#8楼[楼主] 2009-05-15 09:51 金色海洋(jyk)      

多表联合查询 可以现在数据库里面建立一个视图。  回复 引用 查看   

#9楼 2009-05-15 11:55 冰戈      

真有跨数据库跨这么厉害的应用吗?  回复 引用 查看   

#10楼[楼主] 2009-05-15 12:16 金色海洋(jyk)      

据传说,好象有。 就算是没有,那么在SQL Server 2000 里面有多少总分页算法?那种是最好的,或者说是最适合的?您能确定吗? 还有一些项目面临从SQL Server 2000升级到 SQL Server 2005 的问题,SQL Server 2005提供了Row_Number的方式,据说用这个效率更好一点,那么我们要不要更换呢? 如果使用了Pager_SQL的话,那么想换就换,只是修改一下属性罢了,没有什么难度,和复杂度。  回复 引用 查看   

#11楼 2009-05-15 14:04 龙蒸虎豆-JK1983      

大数据量是用游标和临时表,效率高  回复 引用 查看   

#12楼[楼主] 2009-05-15 14:17 金色海洋(jyk)      

@ 龙蒸虎豆-JK1983
pager_sql只负责生成SQL语句,至于哪种方式效率高并不在负责范围内,

其实你也可以加上一个游标和临时表的分页算法上去呀,继承基类写一个子类就可以扩展了。

另外现在pager_sql也提供了一个表变量的分页算法呀。

ps:个人感觉,大数据量的效率高不高完全看能不能利用索引!

如果在可以利用索引的条件下,那么游标一定是最慢的。
 回复 引用 查看   

#13楼 2009-05-15 21:48 redbaby      

想要多表连接使用该方法就要建立视图?不好吧
分页本身并不复杂,不需要这么玄乎
 回复 引用 查看   

#14楼[楼主] 2009-05-15 22:19 金色海洋(jyk)      

@redbaby
不知道您在多表关联的时候是如何分页的,望请赐教?
 回复 引用 查看   

#15楼 2009-05-15 22:22 私家侦探      

access怎么建试图
再建试图就工作就慢了,你也知道现在懒人多,而且还要维护它,最好是能传递个多表连接的查询语句给分页控件,以及第几页,其余就不要管了,这才方便!试图是放内存中,每个药分页的都建试图,有那么多内存吗
 回复 引用 查看   

#16楼 2009-05-15 22:57 代码乱了      

应尽量的避免使用游标,尤其是大数据量的情况  回复 引用 查看   

#17楼[楼主] 2009-05-16 06:46 金色海洋(jyk)      

@私家侦探
维护视图(查询)很难吗?难道比手动写多表关联的SQL语句还难吗?

access有一个叫做“查询”的东东,这个查询可以看成是视图,同时他也可以看成是储存过程。不过这个查询里的多表关联的语法(三个表以上的关联)和SQL Server 里面的语法不太一样。

我只听说储存过程的执行计划会占用内存,什么时候视图的执行计划也会占用内存了?这个是 SQL Server2005的新功能吗?

 回复 引用 查看   

#18楼 2009-05-16 17:24 ddd[未注册用户]

维护视图很麻烦的,三五个人一起做,视图会乱七八糟的  回复 引用   

#19楼[楼主] 2009-05-18 10:16 金色海洋(jyk)      

@ddd [未注册用户]
请问你们用不用储存过程呢?如果用的话,那么你们的储存过程乱不乱呢?
如果不乱的话,那么我也可以告诉你,我的视图也是不乱的。

其实很简单,页面和视图是一对一的,自己只能用自己的视图,不能用别人写的视图,视图的名称使用前缀来区分,甚至可以把编写视图的人的昵称加上。

ps:三五个人一起做一个东东,如果没有规范的话,那么什么都是乱的,不仅仅是视图。
 回复 引用 查看   

#20楼 2009-08-26 16:30 别烦ME、、[未注册用户]

我怎么一点都看不懂 实在是看不懂 能教教我吗??????????  回复 引用   

#21楼 2009-11-03 21:12 斯坦尼斯拉夫斯基      

你的东西实用 不花哨 想法想的也深 谢谢  回复 引用 查看   

#22楼[楼主] 2009-11-04 15:16 金色海洋(jyk)      

引用斯坦尼斯拉夫斯基:你的东西实用 不花哨 想法想的也深 谢谢

谢谢!
俺是从实践中出来的。  回复 引用 查看   

#23楼 2009-11-05 08:03 廉价的感谢![未注册用户]

引用金色海洋(jyk):
引用斯坦尼斯拉夫斯基:你的东西实用 不花哨 想法想的也深 谢谢

谢谢!
俺是从实践中出来的。

 回复 引用   

导航

统计

公告



昵称:金色海洋(jyk)阳光男孩
园龄:5年5个月
荣誉:推荐博客
粉丝:365
关注:130

随笔分类(337)

最新评论