程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> DataGrid基於Access的快速分頁法

DataGrid基於Access的快速分頁法

編輯:關於ASP.NET

DataGrid是一個功能非常強大的ASP.NET Web服務器端控件,它除了能夠方便地按各種方式格式化顯示表格中的數據,還可以對表格中的數據進行動態的排序、編輯和分頁。使Web開發人員從繁瑣的代碼中解放。實現DataGrid的分頁功能一直是很多初學ASP.NET的人感到棘手的問題,特別是自定義分頁功能,實現方法多種多樣,非常靈活。本文將向大家介紹一種DataGird控件在Access數據庫下的快速分頁法,幫助初學者掌握DataGrid的分頁技術。

目前的分頁方法

DataGrid內建的分頁方法是使用諸如“SELECT * FROM <TABLE>”的SQL語句從數據庫表中取出所有的記錄到DataSet中,DataGrid控件綁定到該DataSet之後,它的自動分頁功能會幫你從該DataSet中篩選出當前分頁的數據並顯示出來,其他沒有用的數據將被丟棄。

還有一種方法是使用自定義分頁功能,先將DataGrid的AllowCustomPaging屬性設置為True,再利用DataAdapter的Fill方法將數據的篩選工作提前到填充DataSet時,而不是讓DataGrid幫你篩選:

public int Fill (
 DataSet dataSet, //要填充的 DataSet。
 int startRecord, //從其開始的從零開始的記錄號。
 int maxRecords, //要檢索的最大記錄數。
 string srcTable //用於表映射的源表的名稱。
);

該方法首先將來自查詢處的結果填充到DataSet中,再將不需要顯示的數據丟棄。當然,自定義分頁功能需要完成的事情還不止這些,本文將在後面詳細介紹。

以上兩種方法的工作原理都是先從數據庫中取出所有的記錄,然後篩選出有用的數據顯示出來。可見,兩種方法的效率基本上是一致的,因為它們在數據訪問階段並沒有采取有效的措施來減少Access對磁盤的訪問次數。對於小數量的記錄,這種開銷可能是比較小的,如果針對大量數據的分頁,開銷將會非常巨大,從而導致分頁的速度非常的慢。換句話說,就算每個DataGrid分頁面要顯示的數據只是一個擁有幾萬條記錄的數據庫表的其中10條,每次DataGrid進行分頁時還是要從該表中取出所有的記錄。

很多人已經意識到了這個問題,並提出了解決方法:用自定義分頁,每次只從數據庫中取出要顯示的數據。這樣,我們需要在SQL語句上下功夫了。由於Access不支持真正的存儲過程,在編寫分頁算法上就沒有SQL Server那麼自由了。SQL Server可以在存儲過程中利用臨時表來實現高效率的分頁算法,受到了廣泛的采用。而對於Access,我們必須想辦法在一條SQL語句內實現最高效的算法。

用一條SQL語句取得某段數據的方法有好幾種。算法不同,效率也就不同。我經過粗略的測試,發現效率最差的SQL語句執行時耗費的時間大概是效率最高的SQL語句的3倍!而且這個數值會隨著記錄總數的增加而增加。下面將介紹其中兩條常用的SQL語句。

為了方便接下來的討論,我們先約定如下:

變量 說明 變量 說明 @PageSize 每頁顯示的記錄總數 @MiddleIndex 中間頁的索引 @PageCount 分頁總數 @LastIndex 最後一頁的索引 @RecordCount 數據表的記錄總數 @TableName 數據庫表名稱 @PageIndex 當前頁的索引 @PrimaryKey 主鍵字段名稱 @FirstIndex 第一頁的索引 @QueryFields 要查詢的字段集

變量

定義

@PageCount (int)Math.Ceiling((double)@RecordCount / @PageSize) @FirstIndex 0 @LastIndex @PageCount – 1 @MiddleIndex (int)Math.Ceiling((double)@PageCount / 2) – 1

先讓我們看看效率最差的SQL語句:

SELECT TOP @PageSize * FROM @TableName
WHERE @PrimaryKey NOT IN (
 SELECT TOP @PageSize*@PageIndex @PrimaryKey FROM @TableName
 ORDER BY @PrimaryKey ASC
) ORDER BY @PrimaryKey ASC

這條SQL語句慢就慢在NOT IN這裡,主SELECT語句遍歷的每個@PrimaryKey的值都要跟子SELECT語句的結果集中的每一個@PrimaryKey的值進行比較,這樣時間復雜度非常大。這裡不得不提醒一下大家,平時編寫SQL語句時應該盡量避免使用NOT IN語句,因為它往往會增加整個SQL語句的時間復雜度。

另一種是使用了兩個TOP和三個ORDER BY的SQL語句,如下所示:

SELECT * FROM (
 SELECT TOP @PageSize * FROM (
 SELECT TOP @PageSize*(@PageIndex+1) * FROM @TableName
  ORDER BY @PrimaryKey ASC
 ) TableA ORDER BY @PrimaryKey DESC
) TableB ORDER BY @PrimaryKey ASC

這條SQL語句空間復雜度比較大。如果要顯示的分頁面剛好是最後一頁,那麼它的效率比直接SELECT出所有的記錄還要低。因此,對於分頁算法,我們還應該具體情況具體分析,不能一概而論。下面將簡單介紹一下相關概念,如果您對主鍵和索引非常熟悉,可以直接跳過。

有關主鍵和索引的概念

在 ACCESS中,一個表的主鍵(PRIMARY KEY,又稱主索引)必然是唯一索引(UNIQUE INDEX),它的值是不會重復的。除此之外,索引依據索引列的值進行排序,每個索引記錄包含著一個指向它所引用的數據行的指針,這對ORDER BY的執行非常有幫助。我們可以利用主鍵這兩個特點來實現對某條記錄的定位,從而快速地取出某個分頁上要顯示的記錄。

舉個例子,假設主鍵字段為INTEGER型,在數據庫表中,記錄的索引已經按主鍵字段的值升序排好(默認情況下),那麼主鍵字段值為“11”的記錄的索引,肯定剛好在值為“12”的記錄的索引前面(假設數據庫表中存在主鍵的值為“12”的記錄)。如果主鍵字段不具備UNIQUE約束,數據庫表中將有可能存在兩個或兩個以上主鍵字段的值為“11”的記錄,這樣就無法確定這些記錄之間的前後位置了。

下面就讓我們看看如何利用主鍵來進行數據的分段查詢吧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved