简体   繁体   English

Spring Data Mongodb上的性能问题

[英]performance issue on Spring Data Mongodb

I've got an issue on spring data mongodb, in a method, I request a simple "find" wich retrieve ~1000 Documents. 我在spring数据mongodb上遇到了一个问题,在一个方法中,我请求一个简单的“查找”来检索~1000个文档。

my spring data code is here : 我的春天数据代码在这里:

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);

And with JProfiler, i've got ~1,4sec in the "find" method of MongoTemplate class. 使用JProfiler,我在MongoTemplate类的“find”方法中得到了~1 / 2秒 Note : The request to MongoDB is not the problem, execution take less than 20ms. 注意:对MongoDB的请求不是问题,执行时间不到20ms。 在此输入图像描述

But if try to request the same query with mongo java driver by traditional way : 但是如果尝试通过传统方式使用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;

My method execute in ~140ms ( 10x faster than mongoTemplate style !) 我的方法在~140ms内执行(比mongoTemplate样式快10倍 !) 在此输入图像描述 is there a bug in Spring Data Mongo, or I missed something to configure ? 是否有Spring Data Mongo中的错误,或者我错过了配置的内容? I prefer to write with, it is easier to read, but performance is so poor :'( 我更喜欢写,更容易阅读,但性能很差:'(

the Document class : Document类:

@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;
. . .

EDIT : 1,67sec if I use MongoRepository with the named method : 编辑:1,67sec如果我用MongoRepository与命名方法:

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

在此输入图像描述

EDIT2: logs of spring data : EDIT2:弹簧数据的日志:

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

EDIT 3 : I've expand the call Tree with org.springframework in full view in JProfiler, so I can view what's wrong with Spring Data MongoDB, and here is the majority of time spended : 编辑3:我在JProfiler的全视图中使用org.springframework扩展了调用树,所以我可以查看Spring Data MongoDB的错误,这里大部分时间都是: 在此输入图像描述 2,5 sec total with 总计2.5秒

  • 1,290 calls of 1,290个电话
    org.springframework.data.convert.DefaultTypeMapper.readType (1,462 org.springframework.data.convert.DefaultTypeMapper.readType(1,462
    ms) 女士)

  • 1,290 calls of org.springframework.data.mongodb.core.convert.MappingMongoConverter.read (1,026 ms) 1,290次调用org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(1,026 ms)

And what's the composition of two methods : A majority of Class.forName (erk !) in the first readType 两种方法的组成是什么:第一个readType中的大多数Class.forName(erk!) 在此输入图像描述

And it's less clear on the second call to MappingMongoConverter.read 而第二次调用MappingMongoConverter.read时则不太清楚 在此输入图像描述

I hope it will be easier to find the issue. 我希望找到问题会更容易。

I'm not sure if this applies to your exact case but I had a very similar situation with a lot of time being wasted in ClassUtils.forName() and ClassLoader.load() . 我不确定这是否适用于您的确切情况但我有一个非常类似的情况,在ClassUtils.forName()ClassLoader.load()浪费了很多时间。

I've inspected the situation under the debugger and the root cause in my case was that the class I was trying to deserialize the document to had been moved to a different package. 我已经检查了调试器下的情况,在我的情况下,根本原因是我尝试将文档反序列化的类已被移动到另一个包中。 In this case, Spring Data can't properly cache type information and issues a slow and expensive ClassLoader.load() on the persisted _class field for each document ! 在这种情况下,Spring Data无法正确缓存类型信息,并在每个文档的持久_class字段上发出缓慢且昂贵的ClassLoader.load()

Of course, this class load is doomed to fail because it references a class that no longer exists at the location stored int the _class field of the document. 当然,这个类加载注定要失败,因为它引用了存储在文档的_class字段中的位置不再存在的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM