`

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

    博客分类:
  • SQL
阅读更多

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

<script src="/a_dir_d/ads_250x250.js"></script>

  出处: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

  返回的结果如下:

RowNum EmployeeID LastName FirstName
1 1000 Smith Frank
2 1001 Jackson Lucy
3 1011 Lee Sam
4 1012 Mitchell Jisun
5 1013 Yates Scott
6 1016 Props Kathryn

  ...

5000 6141 Jordan DJ

  注意即使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.455 383
1.405 383
1.434 383
1.394 383
1.365 383
平均: 1.411 平均: 383

  自定义分页

  (从Employees检索一页记录)

持续时间 (秒) 读取数量
0.003 29
0.000 29
0.000 29
0.003 29
0.003 29
平均: 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程序现在或将来有可能让用户翻页查看庞大的数据,那么你用自定义分页是很合适的。

  快乐开发!

<!-- 分页 --><!-- 分页end -->
分享到:
评论

相关推荐

    源代码_ASP.NET 2.0+SQL Server网络应用系统开发案例精解_BLOG

    在《ASP.NET 2.0+SQL Server网络应用系统开发案例精解》一书中,作者深入探讨了如何结合ASP.NET 2.0和SQL Server数据库来构建高效、稳定且功能丰富的网络应用系统。通过实例讲解,读者可以学习到如何设计和实现基于...

    ASP.NET 2.0+SQL Server 2005全程指南-源代码

    ASP.NET 2.0+SQL Server 2005全程指南 目录 基础篇 第1章 ASP.NET概述及环境配置 1.1 认识ASRNET 1.1.1 .NET Framework框架 1.1.2 ASP.NET功能与特性 1.1.3 ASP.NET与ASP的区别 1.2 搭建ASP.NET开发环境 1.2.1...

    ASP.NET 2.0+SQL Server 2005数据库开发与实例 第10章BBS系统录像

    在本教程中,我们将深入探讨如何使用ASP.NET 2.0和SQL Server 2005来开发一个功能丰富的BBS(Bulletin Board System,电子公告板)系统。BBS是一种在线交流平台,允许用户发布消息、参与讨论和分享信息。在这一章中...

    ASP.NET 2.0 + SQL Server 动态网站开发从基础到实践Chapter06

    在本章"ASP.NET 2.0 + SQL Server 动态网站开发从基础到实践Chapter06"中,我们将深入探讨如何在ASP.NET环境中利用SQL Server进行动态网站的数据库交互。这一主题对于任何想要构建功能丰富的Web应用程序的开发者来说...

    ASP.NET2.0+SQL2005开发的简单聊天室系统

    ASP.NET 2.0 和 SQL Server 2005 是微软技术栈中用于构建Web应用程序的强大组合。在这个“简单聊天室系统”项目中,开发者利用了这两种技术的优势,创建了一个支持文本和表情发送的实时交流平台。以下是这个系统中...

    ASP.NET 2.0 + SQL Server 动态网站开发从基础到实践Chapter04

    在本章"ASP.NET 2.0 + SQL Server 动态网站开发从基础到实践Chapter04"中,我们将深入探讨ASP.NET 2.0框架下如何利用SQL Server进行动态网站的构建。ASP.NET Web表单是.NET Framework的核心组件之一,它提供了一种...

    asp.net2.0 大数据量分页

    在 ASP.NET 2.0 中,使用 GridView 控件进行自定义分页需要以下几个步骤: 1. **配置 ObjectDataSource**:设置 SQL 查询,包括上述自定义分页查询。 2. **启用分页**:在 GridView 控件中设置 `AllowPaging="True...

    ASP.NET2.0完全开发指南

    ASP.NET 2.0是微软推出的用于构建动态网站、web应用程序和web服务的框架,它在ASP.NET 1.x的基础上进行了许多改进和增强。在"ASP.NET 2.0完全开发指南"这本书中,读者可以深入理解这个强大的平台,学习如何高效地...

    ASP.net2.0的新特性

    ASP.NET 2.0 是微软.NET Framework的一部分,它在ASP.NET 1.x的基础上引入了许多显著的新特性和增强功能,极大地提升了开发效率和用户体验。以下是ASP.NET 2.0中的主要新特性: 1. **会员(Membership)框架**: ...

    ASP.NET 2.0快速入门(2):ASP.NET 2.0 数据绑定

    数据绑定是ASP.NET 2.0中的一个重要特性,它允许开发者将Web控件(如GridView、ListView、Repeater等)与数据源(如数据库、XML文件或对象集合)关联起来,以便在网页上显示数据。这种绑定过程无需编写大量代码,...

    asp.net 2.0中的数据操作(chm中文版)

    在"asp.net 2.0中的数据操作(chm中文版)"这个资源中,读者可以深入了解到如何在ASP.NET 2.0环境下有效地管理、查询和展示数据。 一、ADO.NET基础 ADO.NET是.NET Framework的核心组件,用于与数据库进行交互。在ASP...

    asp.net2.0实例: blog

    在这个实例中,我们将深入探讨如何使用ASP.NET 2.0和C#语言来开发一个博客系统。 博客系统是Web应用程序的常见类型,它允许用户发布文章、评论、管理个人资料等。在ASP.NET 2.0中,我们可以利用其强大的控件、数据...

    asp.net 2.0分页

    在ASP.NET 2.0中,分页功能被集成到了GridView、ListView和DataList等数据绑定控件中,使得开发者能够轻松地实现数据集的分页显示。下面将详细探讨这一知识点。 首先,理解分页的基本概念。分页是将一个大数据集...

    asp.net 2.0學習資料(51-60)

    ASP.NET 2.0 是微软开发的一个用于构建Web应用程序的框架,它建立在.NET Framework之上,为开发者提供了丰富的工具和功能。本学习资料集包含了51到60个教程,特别适合初学者深入理解ASP.NET 2.0的核心概念和技术。 ...

    ASP.net2.0网站设计及实例源码

    8. ** Membership 和 Role Provider**:ASP.NET 2.0引入了Membership和Role Provider,简化了用户身份验证和角色管理,支持多种存储后端如SQL Server、Active Directory等。 9. **Web部件(Web Parts)**:Web部件...

    Scott Mitchell 的ASP.NET 2.0数据教程

    这是ASP.NET 2.0中用于连接数据库的强大工具,它可以方便地与SQL Server进行交互。Mitchell将解释如何配置SqlDataSource控件,以及如何利用它来绑定到GridView、DetailsView和FormView等数据呈现控件。 3. **...

    ASP.NET 2.0 数据绑定高级技巧

    在ASP.NET 2.0中,数据绑定机制更加完善,支持两种主要的数据绑定模式:声明式数据绑定和编程式数据绑定。 二、声明式数据绑定 声明式数据绑定是在页面标记中直接指定数据源和控件的绑定关系,例如使用控件的...

    【ASP.NET编程知识】在ASP.NET 2.0中操作数据之二十六:排序自定义分页数据.docx

    在ASP.NET中,可以利用SQL Server 2005的ROW_NUMBER()函数来实现这一目标。ROW_NUMBER()为查询结果的每一行分配一个唯一的行号,这使得我们可以按需获取特定范围的行。 例如,以下查询展示了如何获取按ProductName...

    在ASP.NET 2.0中操作数据之二十五:大数据量时提高分页的效率

    总结,提高ASP.NET 2.0中大数据量分页的效率主要依赖于自定义分页策略,包括编写高效的SQL查询(如使用存储过程和SQL Server 2005的分页关键字),以及在DAL和BLL中实现相应的数据获取方法。这种优化方法在处理大量...

Global site tag (gtag.js) - Google Analytics