ASP.NET 2.0在SQL Server 2005上自定义分页

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

 篇文章讲述了如何利用SQL Server 2005的新特性来简单高效的实现分页。对于那些暂时还没用到SQL Server2005的人们,请看在大规模数据中的高效分页方法。如果需要,这篇文章会补上这里讲到的内容。

  出处:http://aspnet.4guysfromrolla.com/demos/printPage.aspx?path=/articles/031506-1.aspx

  介绍

  web开发中普遍会用页面来显示数据。比起整页显示一张报表或者一张数据表的数据给用户,开发者经常用到的是分页显示,每页只显示部分数据,用翻页来控制。在ASPV.NET 1.X里,DataGrid控件使翻页显示变得简单—只需要把属性AllowPaging设置为”true”,并在PageIndexChanged事件中加少量几行的代码就可以实现!ASP.NET 2.0中的控件GridView使事件也简单化了,只需要在GridView的智能面板里把“允许分页”选中,不需要一行代码就可以实现。

  当然了,生活中没有任何事是容易就能做好的。你需要权衡选中一个复选框就能实现的分页方案(或者用DataGrid,写几行代码的实现方案)的性能。如果不选中分页,DataGrid和GridView使用默认分页,简单的把所有数据从头到尾地显示在一张网页上。当数据量小时,几十一百或类似的数量时,效率性能不会太明显。但是,如果你想像这样用默认的分页方法显示上千万、以至几十万的书时就不可行了。

  取代默认分页的方法就是自定义分页,你要做的工作就是用代码来判断并把正确的分页数据取出,可能会费点事,但对于应付如此庞大的数据量来说,绝对值得。我在《ASP.NET Web数据控件快速开发》中讨论了如何在ASP.NET 1.X中实现自定义分页,这篇文章,我们来看在ASP.NET 2.0中如何利用SQL Server 2005的新特性 ROW_NUMBER()来实现自定义分页。(更多关于SQL SERVER的新特性说明,请看利用Microsoft SQL SERVER 2005返回列值。)

  继续读下去来学习更多吧!

  默认分页与自定义分页对比

  在ASP.NET 2.0里GridView(或ASP.NET 1.X里的DataGrid)提供两种分页模型:默认分页与自定义分页。这两种模型在性能与易用性上提供了折中的方案。SqlDataSource控件使用默认分页(尽管你可以在自定义分页了使用它);ObjectDataSource默认使用默认分页模型,不过有个简单的配置可以让它使用自定义分页。心里要时刻记得GridView仅仅是显示数据;它才是GridView负责从数据库中检索数据的数据源控件。

  使用默认分页,每次打开新页显并显示时,都要从GridView的数据源控件中获得所有数据。一旦全部的数据返回,GridView就把所有的数据全显示在页面上,于是用户看到一张页面上显示了如此多的数据。关键要理解这里,无论何时当用户访问第一页或翻到其他页时,所有的数据都会被重新加载一遍。

  举个例子,比如说你在一家电子商务公司上班,你想让用户分页查看你们公司所销售的150中产品。并且,你想每页只显示10条数据。现在,当一个用户访问网页时,所有150条数据都被数据源空间返回过来。但GridView只显示第一个10条数据(产品1到产品10)。再想象一下,当这个用户翻看第二页的数据时,这会引发一个回发的事件,而且在这个时候GridView又会从数据源控件中获得所有的150条记录,但这时只需要显示第二个10条(产品11到产品20)。

缓存与SqlDataSource
SqlDataCourse在对属性EnableCaching做简单设置后允许数据集缓存数据。对于一个缓存的数据集,翻页时不需要再访问数据库,从分页开始到结束都缓存在内存里。然而,初始化页面时相同的问题发生了—所有的数据必须载入到缓存的数据集里去。此外,这样的话你还必须担忧那些过期的数据(虽然你使用了SQL cache dependencies ,但在这里已经没意义了)。

 

  在我不太科学的测试下,发现缓存数据和自定义分页的速度差2倍以上……尽管,你看到缓存方式接近不缓存的方式。(但它始终没有超过自定义分页!)

  更多关于SqlDataSource的数据集缓存,请看利用SqlDataSource缓存数据.

  使用自定义分页,你,开发者,需要做一些工作,但比起盲目的把GridView绑定到一个数据源控件,并且选中“允许分页”复选框,倒不如配置一下数据源控件,使它只检索某一页需要显示的部分数据。这样做的好处是,当显示第一页的数据时,你可以写一段只检索产品1到产品10的sql语句,而不是把所有150条记录全取出来。不过,你的sql语句需要“聪明”的知道怎么把需要的数据从150条记录里剪切出来。

自定义分页的性能优势
我们可以从数据记录的检索能看出自定义分页比默认分页的性能好。在我们的例子里,假设有150条产品数据,每页显示10条。如果用自定义分页,用户挨个浏览这15页的数据,150条数据会分批检索出来;如果用自定义分页,不管哪页150条数据都会被检索出来,导致全部的数据检索量也许是15倍的15条,可能有2250条之多!

 

  虽然自定义分页的性能显而易见,但默认分页却非常简单。所以当数据量小并且数据库服务器的负载也不太重时,我推荐你使用默认分页。如果你有几百、上千以至上万条数据需要分页显示时,一定要使用自定义分页。当然,像分页ASPFAQ.com的数据库,现在的数据量只有200条问答,用默认分页足够了。(当然,如果你觉得数据量将来不会增长,比如可能会维持在75条左右,那你就使用默认分页。但如果将来数据会增长到7500条而你却使用了默认分页,一定会有些客户不高兴的!)

  利用SQL Server 2005高效地取回一页数据

  像早前4Guys 的一篇文章讲述的那样,利用Microsoft SQL Server 2005获得行值中提到的, SQL Server 2005 引入了许多返回行值的关键词。特别提到关键词the ROW_NUMBER()可以返回一列递增的行数。因此,我们可以使ROW_NUMBER()写一条像下面的sql查询语句来获得某页的数据:

SELECT ...
FROM
  (SELECT ...
     ROW_NUMBER() OVER(ORDER BY ColumnName) as RowNum
  FROM Employees e
  ) as DerivedTableName
WHERE RowNum BETWEEN @startRowIndex AND (@startRowIndex + @maximumRows) - 1

  这里的@startRowIndex表示开始行的索引,@maximumRows表示每页显示的最大条数。这条语句会返回ROW_NUMBER()从开始的索引行数到加每页最大条数的行数一部分数据。

  为了使表示跟具体,我们来看下下面这个例子。假设我们有一个表Employees有5000条数据(公司很不错哦!),看下面的查询语句:

SELECT RowNum, EmployeeID, LastName, FirstName
FROM
  (SELECT EmployeeID, LastName, FirstName
    ROW_NUMBER() OVER(ORDER BY EmployeeID) as RowNum
  FROM Employees
  ) as EmployeeInfo

  返回的结果如下:

RowNumEmployeeIDLastNameFirstName
11000SmithFrank
21001JacksonLucy
31011LeeSam
41012MitchellJisun
51013YatesScott
61016PropsKathryn

  ...

50006141JordanDJ

  注意即使EmployeeID字段中间可能有短缺或者可能不是从1开始的,ROW_NUMBER()也会从第1条记录开始,并且稳定增长。因此,如果你想每页显示10条数据,我们想看第3页时,我们知道我们需要的数据是第31条到第40条,我们可以用一个简单的WHERE查询得到。

  配置ObjectDataSource支持自定义分页

  正如前面提到的,一方面,SqlDataSource并没有设计成能提供自定义分页;另一方面,ObjectDataSource被设计成了能支持这个方案。ObjectDataSource被设计成能从一个object读取数据的数据源控件。这个object不管从哪、怎样取出数据,像从一个web 服务、一个数据库、一个文件系统,或一个XML文件……等等。ObjectDataSource并不关心,它就像在数据存储者和数据需要者(像一个GridView控件)之间充当了一个中介。(更多关于ObjectDataSource请看ObjectDataSource控件概述)

  当把一个Web数据控件绑定到一个ObjectDataSource并设置为“允许分页”时,如果你没有具体设置ObjectDataSource来支持自定义分页,会使用默认方案来分页。要使ObjectDataSource支持自定义分页,你需要使一个object来提供以下这些方法:

  1.  一个包含两个整型参数的方法。第一个整数表示检索数据开始的索引位置(起点),而第二个整数表示每页显示的最大条数。这个方法在调用时会返回我们所请求的数据,也就是从检索开始位置到往后每页显示最大条数的准确记录,而不是把所有数据记录都取出来。

  2.  一个返回全部分页的数据记录数量(整数类型)的方法。(这是Web数据控件在在初始化时需要的,这样就可以显示出要分出的总页数或者是是否还需要有下一页。)

  如果你要用到基础的object类型,配置ObjectDataSource来实现分页是很简单的,来看一下下面的这些ObjectDataSource的属性:

  把EnablePaging设置为True

  把SelectMethod设置为提供开始页和开始最大行数的参数以检索数据的方法

  把StartRowIndexParameterName设置为你在SelectMethod中用到的表示检索开始位置的变量;如果你不设置这个,它默认为取startRowIndex的值

  把MaximumRowsParameterName设置为你在SelectMethod用到的每页最大记录数,如果你不设置这个,它默认取maximumROws的值

  把SelectCountMethod设置为返回分页的所有记录的总数的方法

  就这么简单。如果你像这样配置了,那么ObjectDataSource就使用自定义分页了。当然,难点是创建能正确的取出数据的基础对象。但你一旦有了这个基础对象,要实现自定义分页也就配置一下ObjectDataSource的几个属性而已。

  创建一个支持自定义分页的对象

  为了使一个ObjectDataSource绑定到一个GridView,我们需要一个能灵活取得需要数据的底层对象,这个对象还能够返回需要分页的记录数。像约瑟夫校长的文章中写的那样, 《在Visual Studio 2005和中ASP.NET 2.0使用强对象类型》和布莱恩·诺伊斯的文章 《利用Visual studio 2005 数据集设计器做数据访问层》中讲述的那样,在Visual studio 2005中创建能绑定到ObjectDataSource上的对象集是一件很容易的事情。首先要定义取出数据集的存储过程(或sql查询语句),以便让那些强类型的数据集返回数据。

  接下来,在本文的最后提供的,有一个包含5000条职员的范例数据库(大批量增加记录是很容易的)。这个数据库包含了2个自定义分页示例中要用到的3个存储过程:

  GetEmployeesSubset(@startRowIndex int, @maximumRows int) – 返回按EmployeeID排序后从@startRowIndex开始的最多@maximumRows条记录。

  GetEmployeesRowCount – 返回Employees表里的记录总数。

  GetEmployeesSubsetSorted(@sortExpression nvarchar(50), @startRowIndex int, @maximumRows int) – 这个存储过程返回一页经过指定条件排序的数据。也就是说能返回比如支持薪水排序后的记录。(GetEmployeesSubset只能返回按EmployeeID排序的记录。)这个扩展当你需要使用自定义分页中有自定义排序时会用到。

  在这篇文章里我们不计划讲述关于自定义分页中的自定义排序,尽管在这篇文章的下载中也提供了这样的例子;可以通过《自定义分页中的数据排序》看到如何建立自定义分页并支持双向排序……

  创建完这些存储过程以后,我在我的项目里加入一个强类型的数据集文件(Employees.xsd)。然后在里面加入三个与三个存储过程相对应的方法。最后我加入了一个返回EmployeesTableAdapter对象的方法GetEmployeesSubset(startRowIndex,maximumRows)和一个可以设置到ObjectDataSource属性上的方法GetEmployeesRowCount()。(关于创建强类型数据集的详细步骤去看《在Visual Studio 2005和 ASP.NET中使用强类型数据集》和思考特·格思里的博客文章《在VS2005和ASP.NET 2.0中用强类型数据集创建数据访问层》。)

  默认分页与自定义分页性能比较

  在本文最后有关于默认分页与自定义分页的性能比较的数据库(包含一张5000条数据的表),我用SQL和ASP.NET找出性能的差距。(这些测试在我电脑上做是很不严谨的,因为我的电脑还同时运行着其他的程序,虽然结果不能被称做证明,但我想自定义分页的性能在比较中肯定是有优势的。)

  

  SQL查询结果

  默认分页

  (从Employees检索所有记录)

持续时间 (秒)读取数量
1.455383
1.405383
1.434383
1.394383
1.365383
平均: 1.411平均: 383

  自定义分页

  (从Employees检索一页记录)

持续时间 (秒)读取数量
0.00329
0.00029
0.00029
0.00329
0.00329
平均: 0.002平均: 29

  

  ASP.NET测试结果

默认分页
(从Employees查询所有记录)
页面载入时间(秒)
2.34136852588807
2.35772228034569
2.43368277253115
2.43237562315881
2.33167064529151
平均: 2.379363969

自定义分页
(从Employees查询一页记录)
页面载入时间(秒)
0.0259611207569677
0.0280046765720224
0.0359054013848129
0.0295534767686955
0.0300096800012292
平均: 0.029886871

SqlDataSource缓存
(查询所有记录,但缓存它们)
页面载入时间(秒)
2.39666633608461
0.0431529705591074
0.0443528437273452
0.0442313199023898
0.0491523364002967
平均: 0.515511161

  正如你看到的,自定义分页要比默认分页快2倍以上。在相同的数据量下,GetEmployeesSubset(@startRowIndex int,@maximumROws int)要比简单的从Employees表中SELECT查询出所有记录要快470倍。在相同的ASP.NET环境下,自定义分页要比默认分页快120倍。.高负荷的工作量使两者接近,也就是说建立数据库连接和分配任务都会降低性能。不管怎样,在性能方面两个数量级相差太大了。并且这种差距会随着数据量的增加或服务器的性能不同使载入更加明显。

  当缓存是空的时,SqlDataSource方案消耗时间很长,因为它必须到数据库去取得所有数据,缓存在服务器。而服务器有空闲资源时才重新载入(如果只有少量的资源,缓存的数据集就会被清除出内存)并且不再载入。在数据被缓存后,虽然在性能上很接近自定义分页,但0.516秒的平均时间会随着越来越多的缓存数据而接近0.05秒。

  总结

  ASP.NET 1.x中的DataGrid和2.0中的GridView有两种分页方案:默认分页与自定义分页。默认分页很容易做到,但每次访问每个页面都会访问数据库并取出所有数据。而自定义分页非常高效,灵活地取出该取出的那些数据。SQL SERVER 2005由于它的新特性ROW_NUMBER()能取出行数的能力,使取出某段数据简单了。

  如果你做的WEB程序现在或将来有可能让用户翻页查看庞大的数据,那么你用自定义分页是很合适的。

  快乐开发!

asp.net/sql2005 多功能分页(存储过程) 立即下载

相关推荐

SQL Server三种高效率分页方法

1.如果有一个自动增长的id字段,则:   定义二个变量:Page,PageCount   Select top PageCount * From [tb_code] Where id>=(select min(id) from (select top (Page-1)*PageCount+1 id from [tb_code] order by id desc) as t) orde

anihasiyou的专栏 2752

SQL server 高效分页

SELECT w2.n, w1.* FROM XsXXTable w1, (SELECT TOP 130 row_number() OVER (ORDER BY xstim DESC) n, XsID FROM XsTable ) w2 WHERE w1.XsID = w2.XsID AND w2.n > 100 ORDER BY w2.n ASC

大柱子 523

高性能SQLServer分页语句

第一种方法:效率最高 1 2 3 4 5 6 7 8 9 10 11 SELECT TOP 页大小 * FROM( SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1 )as A  WHE...

逸轩 7270

SQL SERVER中,两种比较高效的分页方式

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

qq_18932003的博客 387

Scott Mitchell 的ASP.NET 2.0数据教程之二十五:: 大数据量时提高分页的效率

Scott Mitchell 的ASP.NET 2.0数据教程之二十五:: 大数据量时提高分页的效率 原文 | 下载本教程中的编码例子 | 下载本教程的PDF版导言如我们在之前的教程里讨论的那样,分页可以通过两种方法来实现: 默认分页– 你仅仅只用选中data Web control的 智能标签的Enable Paging ; 然而,当你浏览页面的时候,虽然你看到的只

Freeze_Soul 1250

Custom Paging in ASP.NET 2.0 with SQL Server 2005

IntroductionA common pattern in web development is providing paged access to data. Rather than displaying the enti...

cikeyareng36248的博客 158

ASP.net 2.0 自定义控件的开发之数据分页 第一章

本文将向大家介绍使用ASP.net 2.0 开发自定义的数据分页控件 数据分页的好处 1、减少网络流量 2、提高运行效率 在大数据量时,数据分页是一个必须面对的现实,没有哪个客户愿意花上几分钟或更多的时间来等待。数据分页也有多种方式比如内存分页 SQL Server 存储过程分页等,这里将向大家介绍的是 SQL Server 存储过程分页方式,并结合ASP.net 2.0 的来编写一个通用的...

weixin_33989780的博客 77

对大数据量数据的高效分页25

简介 正如我们在前一篇教程中讨论的那样,分页可以通过两种方式实现 : 默认分页– 只需选中 Web 数据控件的智能标记中的 Enable Paging 选项就可以实现;然而,每次查看页面数据,即使只需在页面中显示部分数据 ,ObjectDataSource 也会读取所有记录。 自定义分页– 仅从数据库中获取用户要求浏览的数据页面需要显示的记录,从而提升了分页的性能;然而与默认分页相比...

weixin_30608131的博客 268

使用asp.net 2.0SQL SERVER 2005构建多层应用

随着.net 2.0的发布,将会使得使用asp.net 2.0来构建的web应用越来越容易。使用asp.net 2.0sql server 2005,将会比asp.net 1.1更方便地构建多层体系架构的web应用。本文,将使用asp.net 2.0sql server 2005.net使用visual studio studio 2005 beta 2sql server 2005使用

Teng_s2000的专栏 1529

ASP.NET 数据分页第一篇—探讨分页原理及 SQL Server 2005 的 ROW_NUMBER 函数

ASP.NET 数据分页第一篇—探讨分页原理及 SQL Server 2005 的 ROW_NUMBER 函数    ASP.NET 的 GridView 控件、SqlDataSource 和 ObjectDataSource 控件,其内建的「数据分页 (pager)」功能,默认做法,是当 user 每次单击 GridView 的页码换页时,都重新去数据库里,把数据表的「所有」数据,「全部」重

thinker28754的专栏 1142

ASP.NET2.0 SQL Server2005构建多层应用

随着.NET 2.0的发布,将会使得使用ASP.NET 2.0来构建的Web应用越来越容易。使用ASP.NET 2.0SQL Server 2005,将会比ASP.NET 1.1更方便地构建多层体系架构的web应用。本文,将使用ASP.NET 2.0SQL Server 2005.net使用Visual Studio 2005 beta 2SQL Server 2005使用...

ah6869的博客 150
上一篇: asp.net程序性能优化的七个方面(转)
下一篇: 在存储过程中实现分页
天下第一刀2020
博客等级 码龄24年 32粉丝 214原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值