解決mongodb查詢慢的問題

來源:互聯網
上載者:User

標籤:解決方案   das   遊標   取數   實現   collect   研究   arp   格式   

    最近項目上一直在用mongodb作為資料庫,mongodb有他的優勢,文檔型類json格式儲存資料,修改起來比傳統的關係型資料庫更方便,但是最近在用mongodb出現了查詢緩慢的問題,我用命令列查詢,顯示速度非常快,而且也添加了索引,2萬條資料只需要十幾毫秒,但是用代碼實現卻需要好幾秒,我調試了代碼發現代碼產生的查詢語句跟我在命令列的查詢語句是一樣的,我當時就很納悶。

    我當時的代碼是這樣寫的:

var list = collection.FindAs<AdClick>(query).SetSortOrder(s).toList();

這是很正常的一行代碼,根據查詢條件,按照排序返回List集合,當我去掉tolist之後,速度就秒查了,然後我看到返回的類型是mongoCursor。這裡我要介紹一下MongoCursor,他是mongo的遊標,他其實並沒有真正的查詢到結果,相當於懶載入,

在調用find時,MongoDB shell並不立即查詢資料庫,而是在等待真正開始擷取資料時才發送查詢。(類似Linq中IQueryable),你可以通過遊標來對最終結果進行控制。比如限制結果數量,略過某一部分,根據任意鍵按任意順序的組合對結果進行各種排序等。當時當你調用ToList()的時候,他就會把查詢資料全部載入到記憶體,如果查詢的資料多,這個過程那個就會很慢,所以真正慢的原因,就是ToList(),知道了慢的原因修改器起來就很好改了。


    但是修改了這個又發現了另外一個問題,那就是Mongodb加查詢條件的count()也會很慢,因為做統計需要得到總數,直接不加查詢條件直接調用Count()比加了查詢條件調用count()快,因為mongodb的查詢是根據索引來的,如果你查詢條件越多,沒有命中查詢條件的索引,就會全文檢索搜尋,所以就會很慢,所以使用count()函數的時候,盡量不加查詢條件,但顯然是不現實的,因為查詢條件會必然很多。 後來在網上看到一個解決方案就是用MongoCursor.Size()方法,果然速度快了很多,不知道原因,沒有仔細研究。


    還有一個問題,就是mongo的分頁問題,你會發現,開始幾頁會很快,越到後面,分頁越慢,這是mongo會把查詢結果載入到記憶體,由於記憶體的限制,越到後面越慢,有什麼解決方案呢? 


 db.test.sort({"amount":1}).skip(100000).limit(10)  //183ms
db.test.find({amount:{$gt:2399927}}).sort({"amount":1}).limit(10)  //53ms
  根據查詢條件載入分頁,只查詢10條資料載入到記憶體,skip分頁貌似很影響效率,不要輕易使用Skip來做查詢,否則資料量大了就會導致效能急劇下降,這是因為Skip是一條一條的數過來的,多了自然就慢了。

解決mongodb查詢慢的問題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.