WEB开发中普遍会用页面来显示数据。比起整页显示一张报表或者一张数据表的数据给用户,开发者经常用到的是分页显示,每页只显示部分数据,用翻页来控制。在ASPV.NET 1.X里,DataGrid控件使翻页显示变得简单—只需要把属性AllowPaging设置为”true”,并在PageIndexChanged事件中加少量几行的代码就可以实现!ASP.NET 2.0中的控件GridView使事件也简单化了,只需要在GridView的智能面板里把“允许分页”选中,不需要一行代码就可以实现。
当然了,生活中没有任何事是容易就能做好的。你需要权衡选中一个复选框就能实现的分页方案(或者用DataGrid,写几行代码的实现方案)的性能。假如不选中分页,DataGrid和GridView使用默认分页,简单的把所有数据从头到尾地显示在一张网页上。当数据量小时,几十一百或类似的数量时,效率性能不会太明显。但是,假如你想像这样用默认的分页方法显示上千万、以至几十万的书时就不可行了。
取代默认分页的方法就是自定义分页,你要做的工作就是用代码来判断并把正确的分页数据取出,可能会费点事,但对于应付如此庞大的数据量来说,绝对值得。我们来看在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 ... |