王振輝 王振鐸 王靜婷
摘要:隨著數據量的不斷增加,使用MongoDB數據庫內置的skip和limit組合分頁算法效率低下,成為影響數據庫訪問性能提升的重要問題。從分析影響分頁查詢速度的關鍵因素入手,提出細粒度查詢改進算法和where-limit算法。通過理論推導和與原算法的實驗結果的比較,分析了兩種新算法使用場景和優(yōu)缺點。將兩種算法應用于實際Web2.0日志系統應用中,取得了較好的效果。最后,對影響數據分頁的其它因素進行了探討,以更好的提高Web應用性能。
關鍵詞:MongoDB;數據分頁;索引;查詢
中圖分類號:TP311.13 文獻標識碼:A
1引言
互聯網時代實際上是數據的時代,構建web2.0應用必然要涉及到海量數據的顯示,數據分頁顯示技術也是開發(fā)過程中經常使用的數據顯示方法,數據分頁效率也是系統性能好壞的重要評價指標。MongoDB由于具有快速、可擴展性,豐富的編程接口及運維方便等特點,使其在大數據時代異軍突起,為web2.0應用提供可擴展的高性能數據存儲解決方案。MongoDB中使用limit函數限制返回的結果數,使用skip函數跳過指定條數的記錄,所以使用limit并結合skip能夠方便的實現數據分頁顯示。此種方法當數據量和并發(fā)訪問量較小時,這樣做分頁完全沒有問題。但是當數據量很大時,skip操作會變的很慢,所以有必要對MongoDB分頁技術進行改進和優(yōu)化,使得其在大數據查詢和顯示方面表現的更好。
目前,國內外對MongoDB分頁技術改進方法主要有以下幾種:一是限定結果集的頁數,類似于搜索引擎結果分頁策略,如:百度、谷歌的方法。雖然,顯示找到的結果巨大,但用戶能查看的只能是前60-70頁的數據,這種方法由于限定結果記錄在萬條以下,所以,獲取頁面數據速度快,但顯示的數據不全。第二種方法是把所有符合條件數據放在數組中,由于也是一次查詢數據庫,且放在內存中,所以,提高了數據分頁的速度。但是,隨著結果集數據的增大,對主機內存要求過大,容易造成內存溢出,Web應用穩(wěn)定性受到影響,同時一次性返回所有記錄,網絡數據通信量較大,系統首次查詢速度過慢。
2細粒度查詢改進算法
2.1設計原理
MongoDB的查詢優(yōu)化方式簡單直接,以查詢模式為單位并行執(zhí)行多種查詢計劃,選取速度最快的。查詢模式的分類是按照查詢的條件和排序涉及的字段及順序進行劃分的。其中排序字段的升序和降序對應的是不同的查詢模式,選取的查詢計劃也不同,通常是相反的索引。MongoDB的查詢模式分類僅考慮查詢條件find和排序sort,并不考慮skip和limit函數。當執(zhí)行查詢結果分頁顯示時,需要使用skip函數跳過一部分數據。在海量數據下,當實際要讀取的數據在sort排序的數據集后面時,skip的數量會很大,有時可以達到幾萬、十幾萬。遇到這樣skip數量的查詢,仍使用原sort排序的索引,速度會很慢。當MongoDB檢測到該查詢計劃速度變慢時,會重新執(zhí)行查詢計劃選取,若檢測使用的查詢也是skip很大的,會導致選取錯誤的索引,造成該查詢模式正常查詢的速度變慢。
針對上述問題,本文提出細粒度查詢改進算法:使用count函數計算總記錄數,并計算數據頁數,在分析查詢語句時,若有skip和limit操作,先計算跳過記錄offset在整個查詢結果集總數recno中占的百分比rate,若rate超過50%,則將該查詢語句劃分到反序的查詢模式,轉換為等價的反序的查詢,這樣就可以減少skip的數量,從而提高提高數據分頁顯示效率。算法改進流程圖如下圖1所示。
下面的代碼給出了顯示數據的后臺核心代碼:
2.2實驗分析
為驗證細粒度查詢改進算法的效果,本文以Web日志系統為例,在結果集記錄數recno分別為10萬,30萬,50萬,比率rate分別為50%,55%,60%,80%的情況下,測試算法優(yōu)化前后的頁面數據顯示在瀏覽器頁面的速度,每個查詢測10次,取平均值,結果如下表1所示:
由結果可知,數據量越大、Skip在總數據量中占的百分比越大,算法改進前后的速度差異越明顯,效果越好。細粒度查詢模式分類方法的確取得了較好的性能。
3Where-Limit優(yōu)化算法
3.1設計原理
Where-Limit算法核心不是計算數據偏移量,而是傳上一頁的數據標記或關鍵詞,根據where條件來查詢實現分頁,這種模式必須有一個連續(xù)的索引,才能通過直接指定位置,查找到要顯示頁的起始數據標記。方法是在程序啟動時將所有數據關鍵詞讀取到數組中,需要分頁的時候通過頁碼記錄和數組下標的對應關系去查詢頁碼首記錄的數據標記,這樣分頁算法也體現了以空間換時間的思想。如果數據本身沒有主鍵的,可以用MongoDB自帶的ObjectId來查,由于基于索引,速度很快。算法原理圖如下圖2所示。
下面的代碼給出了顯示數據的后臺核心代碼:
3.2實驗分析
為驗證Where-limit算法的效果,本文同樣以Web日志系統為例,在結果集記錄數在10萬,30萬,50萬的情況下查詢最后一頁的效率,測試算法優(yōu)化前后的頁面數據顯示在瀏覽器頁面的速度,每個查詢測10次,取平均值,結果如下表2所示:
由結果可知,Where-limit方案由于每次只返回特定頁面的數據,網絡數據傳輸小,同時不再使用Skip函數,不僅比內置skip-limit,同樣與細粒度查詢改進算法比較,分頁速度快且穩(wěn)定可靠。唯一的缺點是關鍵詞數組的大小會對服務器內存要求較高,但可以使用分割數組的方法解決。
4其它分頁因素優(yōu)化
為提高Web2.0數據分頁響應速度,就要盡量節(jié)約帶寬和提高查詢速度。節(jié)約帶寬,即不需要傳輸的數據就不要傳輸,已經查詢的數據可以使用Ajax局部刷新技術,減少傳輸的數據,相當于節(jié)約了帶寬。
查詢速度提高,即在查詢數據庫時,不需要的字段和記錄不返回,只回傳需要的數據,因為Web頁面主要操作都是與數據庫打交道,數據庫查詢速度幾乎是一個網站設計好壞的標準。MongoDB基于其提供的類似于關系數據庫的索引機制實現復雜查詢,數據查詢的速度很大程度上取決于索引的使用。根據查詢創(chuàng)建索引,必要時創(chuàng)建復合索引,MongoDB的查詢優(yōu)化方式簡單直接,在選定了索引之后可以很好地提升性能,但在重復選擇索引時會造成一定的開銷,導致查詢速度變慢。所以若某些應用場景下查詢固定地使用一個索引可以達到最好的性能,程序中可以使用MongoDB提供的hint函數指定索引,避免數據庫無謂的嘗試。同時,使用優(yōu)化方法使Mongodb數據庫負載均勻,也可達到并發(fā)訪問時優(yōu)化服務的目的。
5結論
通過實驗,可以看出,以上各種技術各有優(yōu)缺點和適用場合。使用skip和limit適用于數據量比較少的數據分頁,但隨著數據偏移量變大,分頁效率會大大降低。使用細粒度查詢改進算法在一定程度上可以改進大數據情況下排序靠后的數據頁的數據獲取速度,但對獲取結果集中間數據性能提高不大。Where-limit算法較細粒度查詢改進算法通用性更好,其使用數組存取跳轉頁開始的關鍵詞數據,使用條件和limit進行精確定位,無在結果中進行記錄遍歷情況,效率大大提高,但關鍵值數組在記錄較大時對內存容量要求高,可以使用分割數組來進行優(yōu)化,其次,對于大數據下的分頁,各種方法必須建立索引,所以對增加和修改記錄多的應用會造成一定性能影響。