在MongoDB中一起使用$or和sort()時,查詢效能差的一種解決方案

來源:互聯網
上載者:User

在前面文章曾經提到,在MongoDB中一起使用$or和sort()時,查詢效能會很差,詳見:http://www.cnblogs.com/xinghebuluo/archive/2011/12/01/2270590.html

在mongodb的計劃中,2.5.w版本中可能會修改這個bug。

我的項目中也遇到了這個問題,後來自己想了一個解決方案,暫時規避了這個問題,現在把這個方案分享出來,和大家討論一下.

這個解決方案是受到了mongos的原始碼的啟示,眾所周知mongodb是分布式架構,那麼在我們使用mongos查詢並使用排序的時候,mongos需要把查詢請求發送給各個shard,並將每個shard的查詢結果

存放在一個隊列中(隊列中已經排好序)。這裡假定有2個shard(多個shard的原理是一樣的),查詢條件為{“age”:20},排序條件為:{"time":1},mongos實現如下:

1. mongos首先向兩個shard發送查詢排序命令。

2.兩個shard返回結果是排序後的兩個隊列,。

3.用戶端在取記錄時,mongos取出兩個隊列的第一個元素,判斷time值小的記錄返回給用戶端。

4.用戶端再取記錄時,重複步驟3,從兩個隊列中取time值小的記錄返回給用戶端。

正是受到mongos的啟發,在遇到or查詢並sort的情況時,把or的查詢條件分解為多次查詢,然後實現了一個查詢類,裡面儲存了list<DBObject q>,然後向mongos發起多次查詢排序請求,

此時得到多個cursor,此時的cursor就類似於上面的隊列,即此時得到了多個排序好的隊列,然後經過簡單比較後,依次把記錄返回給用戶端。

例如,此時查詢{"$or":[{"age":20},{"name":"li"}]},排序條件為{"Time":1},可以分解為2次查詢:{"age":20},{"name":"li"},執行查詢後,得到兩個cursor,即兩個隊列,如下:、

此時就可以重複mongos的步驟了,在用戶端取記錄時,對隊列(cursor)中的第一個元素做比較,取出time值最小的記錄返回給用戶端。

該解決方案的優點如下:

1.可以使用索引,速度很快。

2.封裝類後,可以供多個業務使用。

缺點如下:

1. 每個隊列中會緩衝一些記錄,這無形中造成了一些流量浪費和記憶體浪費。

 

上面是我對這個方案的整體思路,歡迎大家討論。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.