前言:经常苦恼mongoTemplate的查询效率太慢,想找出最快的查询方法,测试如下:
@ApiOperation("test")
@GetMapping("/test")
public void test() {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(1181511074567032832L).and("tenant_id").is(1178574081264586752L));
long t1 = System.currentTimeMillis();
mongoTemplate.find(query, FormData.class, "formData");
long t2 = System.currentTimeMillis();
mongoTemplate.findOne(query, FormData.class, "formData");
long t3 = System.currentTimeMillis();
mongoTemplate.findAll(FormData.class, "formData");
long t4 = System.currentTimeMillis();
mongoTemplate.findById(1181511074567032832L, FormData.class, "formData");
long t5 = System.currentTimeMillis();
System.out.println("查询带collectionName");
System.out.println("find()的询时间是:" + (t2 - t1));
System.out.println("findOne()的询时间是:" + (t3 - t2));
System.out.println("findAll()的询时间是:" + (t4 - t3));
System.out.println("findById()的询时间是:" + (t5 - t4));
}
查询带collectionName
find()的询时间是:27
findOne()的询时间是:29
findAll()的询时间是:4022
findById()的询时间是:30
@ApiOperation("test2")
@GetMapping("/test2")
public void test2() {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(1181511074567032832L).and("tenant_id").is(1178574081264586752L));
long t1 = System.currentTimeMillis();
mongoTemplate.find(query, FormData.class);
long t2 = System.currentTimeMillis();
mongoTemplate.findOne(query, FormData.class);
long t3 = System.currentTimeMillis();
mongoTemplate.findAll(FormData.class);
long t4 = System.currentTimeMillis();
mongoTemplate.findById(1181511074567032832L, FormData.class);
long t5 = System.currentTimeMillis();
System.out.println("查询不带collectionName");
System.out.println("find()的询时间是:" + (t2 - t1));
System.out.println("findOne()的询时间是:" + (t3 - t2));
System.out.println("findAll()的询时间是:" + (t4 - t3));
System.out.println("findById()的询时间是:" + (t5 - t4));
}
查询不带collectionName
find()的询时间是:27
findOne()的询时间是:27
findAll()的询时间是:4154
findById()的询时间是:34
find()最快;
findAll()最慢;
带collectionName的查询快于不带的,同时能避免各种子类引发的问题。
find();
public List find(Query query, Class entityClass, String collectionName) {
Assert.notNull(query, "Query must not be null!");
Assert.notNull(collectionName, "CollectionName must not be null!");
Assert.notNull(entityClass, "EntityClass must not be null!");
return this.doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass, new MongoTemplate.QueryCursorPreparer(query, entityClass));
}
findOne();
@Nullable
public T findOne(Query query, Class entityClass, String collectionName) {
Assert.notNull(query, "Query must not be null!");
Assert.notNull(entityClass, "EntityClass must not be null!");
Assert.notNull(collectionName, "CollectionName must not be null!");
if (ObjectUtils.isEmpty(query.getSortObject()) && !query.getCollation().isPresent()) {
return this.doFindOne(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass);
} else {
query.limit(1);
List results = this.find(query, entityClass, collectionName);
return results.isEmpty() ? null : results.get(0);
}
}
发现,findOne()源码中调用了find(),所以findOne()慢于find();
findById();
@Nullable
public T findById(Object id, Class entityClass, String collectionName) {
Assert.notNull(id, "Id must not be null!");
Assert.notNull(entityClass, "EntityClass must not be null!");
Assert.notNull(collectionName, "CollectionName must not be null!");
MongoPersistentEntity> persistentEntity = (MongoPersistentEntity)this.mappingContext.getPersistentEntity(entityClass);
String idKey = "_id";
if (persistentEntity != null && persistentEntity.getIdProperty() != null) {
idKey = ((MongoPersistentProperty)persistentEntity.getIdProperty()).getName();
}
return this.doFindOne(collectionName, new Document(idKey, id), new Document(), entityClass);
}
findAll();
public List findAll(Class entityClass, String collectionName) {
return this.executeFindMultiInternal(new MongoTemplate.FindCallback(new Document(), new Document()), (CursorPreparer)null, new MongoTemplate.ReadDocumentCallback(this.mongoConverter, entityClass, collectionName), collectionName);
}