Java操作MongoDB查询两种计时方式结果差异问题咨询
差异原因说明
- 核心原因:MongoDB Java 驱动的 find 操作为懒加载设计
你调用collection.find(filter)时,仅会在本地内存中构造FindIterable游标对象,不会实际向 MongoDB 服务端发送查询请求,因此你用System.nanoTime统计的只是本地构造对象的开销,自然只有十几微秒的级别。 executionTimeMillis统计的是服务端真实执行查询的耗时
你调用datasetFindIterable.explain()时,会强制触发查询的完整执行流程:MongoDB 服务端会运行完整查询计划、扫描匹配的文档、统计全链路执行指标,返回的executionTimeMillis就是服务端执行整个查询的真实耗时,和你本地构造对象的开销完全不是同一维度的统计值。
另外需要注意:executionTimeMillis仅统计服务端内部的执行耗时,没有包含网络传输、客户端序列化/反序列化的开销,你本地正确计时得到的结果通常会比这个值略大。
正确的本地计时方式
如果要用本地计时统计查询的实际耗时,需要将触发查询实际执行的操作包含在计时范围内,比如调用first()、iterator()、into()等主动拉取结果的方法:
long start = System.nanoTime(); FindIterable<Document> datasetFindIterable = this.collection.find(filter); // 调用iterator()才会实际发送请求到服务端执行查询 MongoCursor<Document> cursor = datasetFindIterable.iterator(); // 若要统计全量数据拉取到本地的总耗时,还需将遍历迭代器的逻辑包含在计时区间内 // while (cursor.hasNext()) { cursor.next(); } long finish = System.nanoTime(); long timeElapsed = finish - start;
内容的提问来源于stack exchange,提问作者chko
相关产品推荐
相关产品推荐

