java Spring Data Mongodb上的性能问题

qoefvg9y  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(197)

我在spring data mongodb上遇到了一个问题,在一个方法中,我请求一个简单的“find”,它检索了~1000个文档。
我的Spring Data 代码在这里:

Query myquery = query(where("ipp").is(ipp).and(CODE_MESURE).in(codes).and(DATE_MESURE).gte(iDateDebut).lt(iDateFin));
return template.find(myquery, MessageMongo.class);

使用JProfiler,我在MongoTemplate类的“find”方法中获得了**~1,4sec**。注意:对MongoDB的请求不是问题,执行时间不到20 ms。

但是如果尝试用传统的方式请求与mongo java驱动程序相同的查询:

final DBCollection collection = template.getCollection(Constantes.MONGO_COLLECTION_MESSAGES_PARAMETRES_VITAUX);
 final DBCursor cursor = collection.find(myquery.getQueryObject());
final List<MessageMongo> tab = new ArrayList<>();
 while (cursor.hasNext()) {
  final DBObject d = cursor.next();
  tab.add(new MessageMongo((String) d.get("origine"), (String) d.get("appareil"),
      (String) d.get("chambre"), (String) d.get("lit"), (String) d.get("uf"), (String) d.get("ipp"),
      (String) d.get("domaineIpp"), (String) d.get("iep"), (String) d.get("domaineIep"), (String) d.get("ej"),
      ((Date) d.get("dateReception")).toInstant(), (String) d.get("codeMesure"),
      (String) d.get("uniteMesure"), (Double) d.get("valeurMesure"), ((Date) d.get("dateMesure")).toInstant()));
 }
return tab;

我的方法在~ 140 ms内执行(比mongoTemplate风格快10倍!)

Spring Data Mongo中是否存在bug,或者我错过了一些需要配置的内容?我更喜欢用写的,它比较容易读,但性能太差了。
文档类:

@Document(collection = Constantes.MONGO_COLLECTION_MESSAGES_PARAMETRES_VITAUX)
public class MessageMongo implements MessageModel {
  @Id
  private String id;
  private final String origine;
  private final String appareil;
  private final String chambre;
  private final String lit;
  private final String uf;
  @Indexed
  private final String ipp;
  private final String domaineIpp;
  private final String iep;
  private final String domaineIep;
  private final String ej;
  private final Instant dateReception;
  @Indexed
  private final String codeMesure;
  private final String uniteMesure;
  private final Double valeurMesure;
  @Indexed
  private final Instant dateMesure;
. . .

编辑:1,67 sec如果我使用MongoRepository和命名方法:

public List<MessageMongo> findByIppAndCodeMesureInAndDateMesureBetween(final String ipp, final List<String> codesMesure, final Instant from, final Instant to);

EDIT 2:Spring数据日志:

2017/12/04 15:44:59,455 INFO  [nio-8180-exec-4] fr.sib.sillage.biometrie.service.impl.MongoMessageService    : findByIppAndCodesBetweenDate ipp=102828799, codes=[147842], dateDebut=2017-12-02T13:46:59,dateFin=2017-12-03T01:46:59  
2017/12/04 15:44:59,482 DEBUG [nio-8180-exec-4] o.s.data.mongodb.repository.query.MongoQueryCreator          : Created query Query: { "ipp" : "102828799", "codeMesure" : { "$in" : [ "147842"]}, "dateMesure" : { "$gt" : { $java : 2017-12-02T12:46:59Z }, "$lt" : { $java : 2017-12-03T00:46:59Z } } }, Fields: null, Sort: null
2017/12/04 15:44:59,517 DEBUG [nio-8180-exec-4] org.springframework.data.mongodb.core.MongoTemplate          : find using query: { "ipp" : "102828799" , "codeMesure" : { "$in" : [ "147842"]} , "dateMesure" : { "$gt" : { "$date" : "2017-12-02T12:46:59.000Z"} , "$lt" : { "$date" : "2017-12-03T00:46:59.000Z"}}} fields: null for class: class fr.sib.sillage.biometrie.model.MessageMongo in collection: parametresVitaux
2017/12/04 15:44:59,517 DEBUG [nio-8180-exec-4] org.springframework.data.mongodb.core.MongoDbUtils           : Getting Mongo Database name=[LilleNoSQLDatabase]
2017/12/04 15:44:59,567 INFO  [nio-8180-exec-4] org.mongodb.driver.connection                                : Opened connection [connectionId{localValue:6, serverValue:3003}] to hades:27017
2017/12/04 15:44:59,567 DEBUG [nio-8180-exec-4] org.mongodb.driver.protocol.command                          : Sending command {find : BsonString{value='parametresVitaux'}} to database LilleNoSQLDatabase on connection [connectionId{localValue:6, serverValue:3003}] to server hades:27017
2017/12/04 15:44:59,592 DEBUG [nio-8180-exec-4] org.mongodb.driver.protocol.command                          : Command execution completed
2017/12/04 15:44:59,796 DEBUG [nio-8180-exec-4] org.mongodb.driver.protocol.command                          : Sending command {getMore : BsonInt64{value=63695089133}} to database LilleNoSQLDatabase on connection [connectionId{localValue:5, serverValue:3004}] to server hades:27017
2017/12/04 15:44:59,862 DEBUG [nio-8180-exec-4] org.mongodb.driver.protocol.command                          : Command execution completed
2017/12/04 15:45:01,213 INFO  [nio-8180-exec-4] fr.sib.sillage.biometrie.service.impl.MongoMessageService    : findByIppAndCodesBetweenDate size=1281

编辑3:
我用org扩展了调用树。springframework在JProfiler中的完整视图,所以我可以查看Spring Data MongoDB的错误,这里是花费的大部分时间:

共2,5秒,带

  • 1 290次呼叫

org.springframework.data.convert.DefaultTypeMapper。readType(1,462
ms)

  • 1,290次访问 www.example.com (1,026 ms)

两种方法的组成是什么:班级的大多数。forName(erk!)在第一个readType x1c4d 1x中
在第二次调用www. example时就不太清楚 www.example.com

我希望能更容易找到问题。

lp0sw83n

lp0sw83n1#

我不确定这是否适用于您的确切情况,但我在ClassUtils.forName()ClassLoader.load()中遇到了非常类似的情况,浪费了大量时间。
我已经检查了调试器下的情况,在我的情况下,根本原因是我试图反序列化文档的类已经被移动到不同的包中。在这种情况下,Spring Data无法正确缓存类型信息,并在持久化的_class字段上为每个文档发出一个缓慢且昂贵的ClassLoader.load()
当然,这个类加载注定会失败,因为它引用了一个在文档的_class字段中存储的位置不再存在的类。

相关问题