在网上年到很多网站都写了不少关于DataGrid实现分页的方法,分页一直是很多初学ASP.NET的人感到棘手的问题,特别是自定义分页功能,实现方法多种多样,非常灵活。使用分页的缺点是DataGrid控件绑定到该DataSet之后,它的自动分页功能会帮你从该DataSet中筛选出当前分页的数据并显示出来,其他没有用的数据将被丢弃,对于小数量的记录,这种开销可能是比较小的,如果针对大量数据的分页,开销将会非常巨大,从而导致分页的速度非常的慢。换句话说,就算每个DataGrid分页面要显示的数据只是一个拥有几万条记录的数据库表的其中10条,每次DataGrid进行分页时还是要从该表中取出所有的记录。
很多人已经意识到了这个问题,并提出了解决方法:用自定义分页,每次只从数据库中取出要显示的数据。这样,我们需要在SQL语句上下功夫了。由于Access不支持真正的存储过程,在编写分页算法上就没有SQL Server那么自由了。SQL Server可以在存储过程中利用临时表来实现高效率的分页算法,受到了广泛的采用。而对于Access,我们必须想办法在一条SQL语句内实现最高效的算法。用一条SQL语句取得某段数据的方法有好几种。算法不同,效率也就不同。我经过粗略的测试,发现效率最差的SQL语句执行时耗费的时间大概是效率最高的SQL语句的3倍!而且这个数值会随着记录总数的增加而增加。至于如何实现Access的快速分页的代码很多网站都有介绍,具体内容俺就不在此写这么多了。
本文将针对各网站的Access数据库下的快速分页法的SQL句子修正了一些bug并转换成vb.net语法,以下是完整的函数:
1 ''' <summary> 2 ''' 获取根据指定字段排序并分页查询的 SELECT 语句。 3 ''' </summary> 4 ''' <param name="pageSize">每页要显示的记录的数目。</param> 5 ''' <param name="pageIndex">要显示的页的索引。</param> 6 ''' <param name="recordCount">数据表中的记录总数。</param> 7 ''' <param name="tableName">要查询的数据表。</param> 8 ''' <param name="queryFields">要查询的字段。</param> 9 ''' <param name="primaryKey">主键字段。</param> 10 ''' <param name="ascending">是否为升序排列。</param> 11 ''' <param name="condition">查询的筛选条件。</param> 12 ''' <returns>返回排序并分页查询的 SELECT 语句。</returns> 13 ''' <remarks></remarks> 14 Public Shared Function Paging(ByVal pageSize As Integer, ByVal pageIndex As Integer _ 15, ByVal recordCount As Integer, ByVal tableName As String, ByVal queryFields As String _ 16, ByVal primaryKey As String, ByVal ascending As Boolean, ByVal condition As String) As String 17 Dim sb As New StringBuilder() 18 Dim pageCount As Integer = GetPageCount(recordCount, pageSize) ’分页的总数 19 Dim middleIndex As Integer = GetMidPageIndex(pageCount) ’中间页的索引 20 Dim firstIndex As Integer = 0 ’第一页的索引 21 Dim lastIndex As Integer = pageCount - 1 ’最后一页的索引 22 23 If pageIndex <= firstIndex Then 24 sb.Append("SELECT TOP ").Append(pageSize).Append(" ").Append(queryFields) _ 25.Append(" FROM ").Append(tableName) 26 27 If condition <> String.Empty Then 28 sb.Append(" WHERE ").Append(condition) 29 End If 30 sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) 31 End If 32 33 If pageIndex > firstIndex AndAlso pageIndex <= middleIndex Then 34 sb.Append("SELECT TOP ").Append(pageSize).Append(" ").Append(queryFields).Append(" FROM ") _ 35.Append(tableName).Append(" WHERE ").Append(primaryKey) 36 If ascending Then 37 sb.Append(" > (").Append(" SELECT MAX(") 38 Else 39 sb.Append(" < (").Append(" SELECT MIN(") 40 End If 41 sb.Append(primaryKey).Append(") FROM ( SELECT TOP ").Append((pageSize * pageIndex)) _ 42.Append(" ").Append(primaryKey).Append(" FROM ").Append(tableName) 43 44 If condition <> String.Empty Then 45 sb.Append(" WHERE ").Append(condition) 46 End If 47 sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) _ 48.Append(" ) TableA )") 49 50 If condition <> String.Empty Then 51 sb.Append(" AND ").Append(condition) 52 End If 53 sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) 54 End If 55 If pageIndex > middleIndex AndAlso pageIndex < lastIndex Then 56 sb.Append("SELECT").Append(" ").Append(queryFields).Append(" FROM ( SELECT TOP ") _ 57.Append(pageSize).Append(" ").Append(queryFields).Append(" FROM ") _ 58.Append(tableName).Append(" WHERE ").Append(primaryKey) 59 If ascending Then 60 sb.Append(" < (").Append(" SELECT MIN(") 61 Else 62 sb.Append(" > (").Append(" SELECT MAX(") 63 End If 64 sb.Append(primaryKey).Append(") FROM ( SELECT TOP ") _ 65.Append((recordCount - pageSize * (pageIndex + 1))) _ 66.Append(" ").Append(primaryKey).Append(" FROM ").Append(tableName) 67 68 If condition <> String.Empty Then 69 sb.Append(" WHERE ").Append(condition) 70 End If 71 sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(Not ascending)) _ 72.Append(" ) TableA )") 73 74 If condition <> String.Empty Then 75 sb.Append(" AND ").Append(condition) 76 End If 77 sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(Not ascending)) _ 78.Append(" ) TableB ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) 79 End If 80 If pageIndex >= lastIndex Then 81 sb.Append("SELECT").Append(" ").Append(queryFields).Append(" FROM ( SELECT TOP ") _ 82.Append((recordCount - pageSize * lastIndex)).Append(" ").Append(queryFields).Append(" FROM ").Append(tableName) 83 If condition <> String.Empty Then 84 sb.Append(" WHERE ").Append(condition) 85 End If 86 sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(Not ascending)) _ 87.Append(" ) TableA ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) 88 End If 89 Return sb.ToString() 90 End Function
修正bug后的sql语句支持多条件查询,具体详见http://www.web3.cn/vs2005/RepeaterPage_Access.aspx(本演示只做了一万多条记录的演示,使用快速分页的方法速度明显示比没有使用前要快得多)或本站的“技术交流“。本文就到这吧,还有很多地方需要大家在平时工作和学习中不断总结经验,在解决实际问题时尽可能找到最有效的方法。