Pages

2012-07-28

資料Grid分頁的數據效能考量

在Web後台管理,我們習慣使用Grid控件(DataGrid, GridView)來呈現Table的資料,資料一多當然會使用UI分頁:
Grid Paging

實際上UI切換頁次時,背後程序仍是向數據庫下達完整數量的Select指令,只是UI上呈現一頁而己。假設該Table有上百萬筆資料,在無法使用Where過濾條件下,取回的效能會很差。

ASP.NET為此提供了ObjectDataSource控件,它有StartRowIndex、MaximumRows與Sort欄位等參數名稱,可以只向數據庫取回該頁資料就好,然而每個Table性質不一樣,查詢條件又不同,實作該強型別(Strong Typed)類別實在是不好維護。尤其使用SQL Server時,它仍不支援LIMIT index, count等分頁語法,得寫成下面冗長的分頁Select語法:SQL Paging

這種複雜的分頁SQL語法,且不論SQL Server效能如何,程序員要維護這樣語法就很痛苦。因此有些程序員乾脆不實作真正背後數據分頁,而是在查詢介面硬加上「最大筆數」限制,至少就避免了載入大量資料的問題。
Search TopRow

在後台管理介面裏,這算可接受的中間作法,不過在前端顯示頁面裏,「最大筆數」最終限制了資料呈現,怎麼辦呢?最終我基於方便維護程式的原則下,將所有ObjectDataSource控件統一指向一個強型別空殼物件,將其中最重要的Select(), SelectCount()函式透過Delegate指到執行頁面的程式碼裏,就省去了帶入SQL Parameters及得實作該Class的麻煩。

至於T-SQL的分頁複雜語法,發現它的ROW_NUMBER()還得帶入一個Sort欄位指定,真是既難用又雪上加霜。為了日後相容別的資料庫(MySQL, SQLite),仍使用LIMIT 10,10的語法,再用個轉換函式將它自動轉成T-SQL的分頁複雜查詢語法,如此可以達到程式碼易維護目的。
Source Code
 
結論,編程世界裏處處充滿阻礙與困難,Hold住堅持下來不亂寫,工作才會有成就及樂趣。

No comments: