首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

DataGrid 基於 Access 的高效分頁演算法:主鍵定位法

     編輯:關於ASP.NET

DataGrid 是功能非常強大的 ASP.NET Web 伺服器端控制項,除能方便按各種方式格式化顯示表格資料,還可對表格資料動態排序、編輯與分頁。使 Web 開發人員從繁瑣程式碼中解脫。實現 DataGrid 分頁功能一直是很多初學 ASP.NET 人感到棘手問題,特別是自訂分頁功能,實現方法多種多樣、非常靈活。本文介紹一種 DataGrid 控制項在 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