Spring Data MongoDB排序性能

时间:2014-10-22 08:12:08

标签: java spring mongodb spring-data spring-data-mongodb

我发现Spring Data MongoDB排序性能存在显着差异,具体取决于方向。我正在对一个属性进行排序,并在两个方向都有索引。当按升序排序时,响应时间约为80毫秒,当排序下降时大约为2.7秒。 原生查询分别需要5毫秒和50毫秒。后续页面的查询速度稍快,大约1秒。

对于我的申请,2.7秒是不可接受的,我能做些什么吗?

控制器:

String q = URLDecoder.decode(query);
Sort.Direction d = Sort.Direction.ASC;

if (direction == -1) {
    d = Sort.Direction.DESC;
}

String[] properties = sort.split(",");
Sort s = new Sort(d, Arrays.asList(properties));
Pageable p = new PageRequest(page, size, s);

List<Employer> list = employerRepository.find(q, p);

存储库:

@Override
public List<Employer> find(String query, Pageable page) {
    Query q = new BasicQuery(query).with(page);
    return mongoTemplate.find(q, Employer.class);
}

更新1:我在MongoDB上启用了性能分析,本机和Spring Data查询看起来完全相同。所以似乎瓶颈在于mongoTemplate.find(q, Employer.class);

1 个答案:

答案 0 :(得分:1)

我认为尽管sortDBCursorPageable之间存在联系,但我们认为Spring数据不会直接归咎于您所遇到的相当差的性能。< / p>

Spring Data使用DBCursor来读取特定DBCollection的值。根据提供的Pageable参数sort,设置了skiplimit。查询执行后,DBCursor将按预期关闭。

显然,如果您可以在中间重用游标,那么您将获得更好的性能,但这会引入可能导致其他问题的共享状态。

但是,让我们仔细看看当我们尝试浏览结果时会发生什么,而不是重用光标,只使用简单的MongoDB驱动程序API进行排序和不进行排序。

对于该示例,我们使用具有10.000 Person个元素的集合,其名称范围为“foo0”到“foo10000”。

for (int pageNumber = 0; pageNumber < 1000; pageNumber++) {
    DBCursor c = collection.find(new BasicDBObject("name", new BasicDBObject("$regex", "foo*")))
        .skip(pageNumber * 10)//
        .limit(10)//
        .sort(new BasicDBObject("name", -1)); // comment this line to see the difference

    DBObject o = null
    while (c.hasNext()) {
        o = c.next();
    }
    c.close();
}

这会在我的计算机上48278 ms,而没有排序条款,这会落到2862 ms

如果你不使用Spring Data MongoDB也会发生这种情况我认为这个问题的原因更可能在MongoDB java驱动程序中找到,但是此时我找不到匹配的问题了MongoDB问题跟踪器......