spring - Mongodb 聚合仅在 Spring Data 上缓慢

标签 spring mongodb spring-boot spring-data spring-data-mongodb

我正在使用带有 Spring Data 的 Spring Boot 2 和本地 Mongodb 3.4。 我目前有一个包含约 20 万个文档的集合,通过 Spring 的注释正确索引。

我制作了一个聚合管道(见本文底部),需要大约2000ms才能完成:Python、Studio3T、Spring Boot 单元测试

当我在应用程序的部署实例(bootJar)上正常运行相同的查询时,需要8000ms,这对于我的用例来说是 Not Acceptable ,而且也是很奇怪。

数据库日志报告在所有情况下的查询时间约为 300 毫秒,因此数据库性能良好。

找出发生这种情况的原因非常有趣,因为正常部署和单元测试期间的代码完全相同(也使用相同的参数),因此在性能上应该具有可比性。

我的猜测是部署和测试之间的配置有所不同。我在两个环境中都使用默认设置(没有针对 mongo 的特定 bean 声明,只是 Autowiring MongoOperations 并享受“启动魔法”)。


以下是一些示例:

文档如下所示:

{ 
  "_id" : ObjectId("5b4f76696d370f30d401f246"), 
  "description" : "IoT420", 
  "timestamp" : NumberLong(1530286316), 
  "sensor" : "Temperature", 
  "value" : 30.02, 
  "class" : "net.derp.iot.piws.entities.dto.MongoMeasurementRepr"
}

聚合管道:

Aggregation aggregation = newAggregation(
            match( where( "description" ).is( filterDescription ) ),
            match( where( "sensor" ).is( sensorName ) ),
            match( where( "timestamp" ).gte( tsFrom ).lte( tsTo ) ),
            sort( Sort.Direction.ASC, "timestamp" ));

此聚合返回大约 120k 文档。

我使用System.nanoTime()来测量时间。


更新:删除runtime('org.springframework.boot:spring-boot-devtools')后,时间下降到5000ms,这仍然比测试用例慢。我怀疑某种“验证”在测试过程中被禁用。

最佳答案

我浏览了您的查询,发现您在两个比赛阶段后给出了时间戳标准。理想情况下,日期条件应该放在 mongo 查询中的第一位,因为它可以缩小下一阶段要扫描的文档数量。

所以你的聚合查询应该是

Aggregation aggregation = newAggregation(
            match( where( "timestamp" ).gte( tsFrom ).lte( tsTo ) ),
            match( where( "description" ).is( filterDescription ) ),
            match( where( "sensor" ).is( sensorName ) ),
            sort( Sort.Direction.ASC, "timestamp" ));

关于spring - Mongodb 聚合仅在 Spring Data 上缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51410704/

相关文章:

java - Spring MVC : default view objects

windows - 如何在 Windows 启动时停止 mongodb 服务器?

templates - 使用 thymeleaf 用父布局包装模板

java - Spring Boot 自定义字段验证

java - 访问由 Spring 的类转换器创建的对象上的 getter 时出现 ArrayIndexOutOfBoundsException

java - 如何在 Spring 中将一个 Bean 注入(inject)到一组 Bean 中?

java - Ajax 调用不同的 Controller

java.lang.NoSuchMethodError : org. apache.poi.util.POILogger.log(I[Ljava/lang/Object;)V

Mongodb聚合5分钟

javascript - 如何返回 mongoDB 中具有连字符字段的映射函数