Access分頁方案
開門見上,本文主要是回答一下三個問題:
- Access是否存在更有效率的分頁方法?
- 現有Access大數據量10萬條數據分頁的效率測試
- Access的數據承載量到底有多大?
相信很多ASP的站點還在使用Access數據庫,因為Access數據庫無須開專門的數據庫空間,調用,遷移也方便,節省費用。另外對網站搭建者的專業能力要求也相對低一些。但隨著網站的運行,數據庫體積越來越大,數據量也從最初的幾百條到了現在的上萬條,上十萬條甚至更多。于是因數據應用級別的改變帶來的各種各樣的應用問題出現了。而其中大數據量的列表分頁效率問題更是讓很多人頭疼。筆者隨便通過“大數據量分頁效率”,“Access 分頁”等關鍵詞分別百度和谷歌了一下,發現有此疑問的大有人在。很多網頁上也給出了不同的解決辦法。那么,這些方法到底能達到優化效率,提高速度的目的嗎?
先讓我們來看看以下的幾個Access分頁優化方案,當然如果你直接將數據庫升級到SQL Server,那么有更好的諸如存儲過程等方法。今天我們就討論一下Access大數據量優化分頁方法,以及Access到底能承受多少數據量。
方案一:利用ado本身的結果集的pagesize,AbsolutePage的屬性來進行分頁
程序示例:(僅供示意,完善的各種條件判斷自行添加)
- MaxPerPage=20
- page=cint(request("page"))
- sql="select * from 表 where 條件 order by 排序條件"
- set rst=server.CreateObject("adodb.recordset")
- rst.open sql,conn,1,1
- rst.pagesize=MaxPerPage
- rst.AbsolutePage = Page '將記錄定位到對應頁數的第一條
- for i=1 to MaxPerPage 循環列表
- rst.movenext
- if rst.eof then exit for
- next
這個方法是最為常用的Access分頁方法。
缺點:每次都要讀入符合條件的所有記錄,然后再定位于對應頁的記錄。當數據量大的時候,效率就十分的低下。
與此相似的方法是利用ado的move方法,每次將記錄集游標移動 (page-1)*pagesize ,就實現了了記錄的分頁。經過測試,效率與方案一大致相同。
方案二:
1.設置一個自增長字段.并且該字段為INDEX.
2.由于是 Access ,所以,只能是前臺分頁.自增長字段目的,就是為了實現分頁功能.
1> 記錄用戶前頁的最后一個 自增值 ,例如 M .
2> 下一頁,取下一頁的開始值.M+1 ,結束值: M+1+1.5*PAGESIZE (注:由于數據庫會有增刪操作,故應該取頁大小應該有一個系數,你可以根據情況自定一個1大的系數.
3> 前臺循環取 RS 的前 PAGESIZE 條, 寫到一個 新的RS中,并返回.
這個方案通過自增值來分部截取不同分頁的數據列表,文中考慮到數據庫有增刪操作,所以加入了一個系數的概念,這是一個不得已的做法。這個方案可以保證分頁效率,但只能運用于增刪不太頻繁(自增值字段相鄰記錄的值相差不多的情況)的數據表。
方案三:not in 方法。
這個方案在很多網站上都轉載。據說對于越往前的分頁效率提高越明顯。我一直有所懷疑,因為“not in”本身就是個耗費資源的算法。很難相信一個低效率的方法能提高大數據量分頁的效率。示例如下:
- sql="select top 12 * from 表 where Id not in(select top page*pagesize Id from 表 order by id desc) order by Id desc"
如果是第9頁,每頁20條即
- select top 20 * from 表 where Id not in(select top 9*20 Id from 表 order by id desc) order by Id desc
原理即:選擇top 20 的記錄,條件是id不在前面分頁的記錄ID里。通過這種方式過濾掉前面分頁的記錄,然后通過top高效率的方式獲取當頁的記錄。
“top”確實高效,但是“not in”呢?
于是我直接用這種方法測試了一下,測試條件:10萬條數據。點擊查詢.......... MY GOD,長時間無響應,最后Ctrl+Alt+Delete 結束任務。再試,結果同樣如此。于是改變一下測試條件,變成1000條數據,OK,結果顯示非常順利。
結論:如果你是大數據量分頁,還是不要用這種方法,會死人的。
方案四:
- "select * from (select top "&pagesize&" * from (select top "&page*pagesize&" * from 表" order by id desc) order by id) order by id desc"
這個方法簡單說來,就是選取當前頁及小于當前分頁的所有記錄,再通過“Top”方式選取當前頁的記錄。
這個方法沒有出現效率低的語句,雖然至少要select兩次(示例select了三次是為了排序)。但是效率應該不錯。且越靠前的分頁應該越明顯。
如果還想節省效率,可以只select兩次。
假如記錄ID為1-100,每頁5條。現在顯示第4頁,排序為倒序。
執行順序:
1) 選擇前4頁的數據,即100-81共20條數據
2) 從這20條數據中選擇最小的5條,即81-85。
3) 將選擇的5條按倒序排,即成為 85-81。
如果節省第三步也可,只不過顯示變成
第一頁:96,97,98,99,100
第二頁:91,92,93,94,95
其實也不錯。
光說沒用,最終看測試結果。我在相同的數據條件,服務器配置下,分別對方案一中的兩種方法和方案四進行了Access分頁效率測試,測試數據如下
測試條件:
>10萬條;pagesize=20;
分頁總數>5000頁;
順便也進行了一下“select 部分字段”和“select 所有字段”的對比測試。
從上面的測試結果來看,方案三的優勢還是比較明顯的。而到5000頁的效率基本上和前兩種方法差不多,甚至仍然有一定得優勢。
另外,很多人在寫select語句時, 習慣 select * from 表,這不是一個好習慣。上面的Access分頁測試結果表明,還是按需索要,按需供應的好,需要什么字段,就select什么字段。能夠極大的節省服務器資源。
很多網友提到Access時都不免的輕視,“你還在用Access?”,“還不換SQL Server?”,“用Access你還想多快?”。其實在我的經驗看來,即便是在10萬條的應用級別上。Access常常比SQL Server快。因為SQL Server需要額外連接,且多了一個帶寬連接因素的影響(當然,網站服務器和數據庫服務器運行速度和帶寬都很OK,那沒話說)。
SQL Server 在更高數據級別上的速度優勢還是比較明顯,畢竟與Access不是一個級別的產品。
為了探索一下Access數據庫的極限。在40萬條數據的情況下進行了上述分頁測試。速度確實大打折扣。但是第三種方案在一萬頁內還是表現不錯的。此時數據庫已經達到400多兆。再結合之前處理過的幾個4,500兆的Access數據庫。我認為40萬條數據是Access數據庫在一般應用的一個界限,但不是極限。超過這個數,就需要在程序優化上做太多的工作。就有些不太值了。
原文鏈接:http://www.cnblogs.com/huanghai/archive/2011/03/19/1988627.html
【編輯推薦】