MongoTemplate下count的查詢優(yōu)化問題

眾所周知, mongo db的count查詢是相當(dāng)慢的, 但是count的查詢又是非常常見的作用.

筆者最近就有一項需要,需要在200萬條數(shù)據(jù)中執(zhí)行count查詢,并且使用MongoTemplate.count()查詢,結(jié)果查詢結(jié)果很慢.

那么如何解決這個問題呢? 筆者查詢了相關(guān)的資料. 采用了以下方案供大家參考.

首先,筆者在mongo shell中執(zhí)行db.collection.find({}).count()不用1s的時間就出來結(jié)果, 因此, 筆者首先想到的是能不能再java mongo中直接執(zhí)行mongo shell的命令, 很不幸, 筆者使用的是4.4版本的mongodb, 不在支持db.eval()操作. 因此只能選擇其他方法

相關(guān)資料可以參考這個:

https://stackoverflow.com/questions/16239592/raw-javascript-mongodb-queries-using-db-eval-in-java

https://docs.mongodb.com/manual/reference/method/db.eval/

經(jīng)過網(wǎng)上查詢和官方文檔提示, mongodb支持以下的count查詢

  • db.collection.count()
  • db.collection.countDocuments()
  • db.collection.estimatedDocumentCount()

這三個方法對比著看,會有更深的認識

方法對比

count

  1. 采用metadata來返回數(shù)據(jù)總量

countDocuments

  1. 未采用metadata
  2. 通過aggregation來實時計算出數(shù)量

改語法封裝了下面的語句,來返回數(shù)量

db.collection.aggregate([
    {$match: <query>},
    {$group: {_id: null, n: {$sum: 1}}}
])

estimatedDocumentCount

說明

  1. 該方法返回一個collection中的所有documents的數(shù)量
  2. 該方法封裝了count命令
  3. 該方法采用了metadata

使用

db.collection.estimatedDocument(<options>)

使用示例

綜合上述三個方法的對比. 在計算count的時候, 根據(jù)查詢條件的不同,可以采用不同的方法

  • 如果沒有查詢條件,即查詢總量時,建議采用estimatedDocumentCount方法
  • 如果有查詢條件, 只能通過countDocuments方法, 并且減以在查詢條件增加索引.

Java代碼片段示例

import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.MongoTemplate;


long count = 0;
if (query.getQueryObject().isEmpty()) {
    LOGGER.info("[Mongo] ==> 開始查詢總量");
    long startTime = System.currentTimeMillis();
    count = mongoTemplate.getCollection(tableName).estimatedDocumentCount();
    LOGGER.info("[Mongo] ==> 結(jié)束查詢總量,耗時:{}ms", System.currentTimeMillis() - startTime);
} else {
    LOGGER.info("[Mongo] ==> 開始條件查詢總量");
    long startTime = System.currentTimeMillis();
    count = mongoTemplate.count(query, tableName);
    LOGGER.info("[Mongo] ==> 結(jié)束條件查詢總量,耗時:{}ms", System.currentTimeMillis() - startTime);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容