简体   繁体   English

MongoDB + SpringData查询非常慢

[英]MongoDB + SpringData Query very slow

I have this simple class: 我有这个简单的课程:

@Document (collection = "advertise")
public class AdvertiseCache {
    @Id
    private int id;

    private int brandId;
    private String brandName;
    private String modelName;

    @Indexed
    private int odometer;

    @Indexed
    private int price;
    private boolean learner;
    private int manufacturedYear;
    private double engineSize;
    private String transmissionTypeName;
    private String stateName;
    private String ownerTypeName; //private/dealer
    private String conditionTypeName; //new/used
}

I have another class with same attributes but annotated with @Entity. 我有另一个具有相同属性但使用@Entity注释的类。

They are stored in MongoDB and respectively in PostgreSQL. 它们分别存储在MongoDB和PostgreSQL中。

I am using Spring Data JPA for PostgreSQL and Spring Data MongoDB ... for mongo. 我正在使用Spring Data JPA for PostgreSQL和Spring Data MongoDB ... for mongo。

Both databases contain same data, 30 rows. 两个数据库包含相同的数据,30行。

  • 10000 queries of type findAll will cost: Mongo ~8000-9000ms and PostgreSQL ~10000-11000ms 10000个findAll类型的查询将花费:Mongo~8000-9000ms和PostgreSQL~10000-11000ms

  • 10000 queries of type findAll where price >= 1 and price <=9000 and odometer >=1 and odometer <= 40000 will cost: Mongo: ~7000ms and PostgreSQL ~7200ms 10000个查询类型为findAll,其中price> = 1且price <= 9000且odometer> = 1且里程表<= 40000将花费:Mongo:~7000ms和PostgreSQL~7200ms

WHY? 为什么? Am I doing something wrong? 难道我做错了什么? I was expecting mongo much faster. 我期待mongo更快。 (I my application rarely I am using just find all. Most of the times I use filters for sorting) (我的应用程序很少使用我只是找到所有。大多数时候我使用过滤器进行排序)

Both servers are running in a FreeBSD 9 virtual machine. 两台服务器都在FreeBSD 9虚拟机中运行。 I tested this on another VM with CentOS 6.3. 我在另一台运行CentOS 6.3的虚拟机上测试了这个。 Similar results +-100ms. 类似的结果+ -100ms。

Tnx TNX

/// more code for explanations (my filter builder will contain only odometerMin, odometerMax for between criteria and priceMin and priceMax for between criteria: ///更多解释代码(我的过滤器构建器将仅包含odometerMin,odometerMax用于标准之间,priceMin和priceMax用于标准之间:

public List<AdvertiseCache> findByFilter(FilterBuilder filter) {
    List<AdvertiseCache> result = null;
    Query query = new Query();
    Criteria criteria = new Criteria();
    criteria = criteria.and("price").gte(filter.getPriceMin()).lte(filter.getPriceMax());
    criteria = criteria.and("odometer").gte(filter.getOdometerMin()).lte(filter.getOdometerMax()); 
    query.addCriteria(criteria);
    query.limit(filter.getLimit());
    query.skip(filter.getOffset());
    result = mongoTemplate.find(query, AdvertiseCache.class, collectionName);
    return result;
}

I am not sure I get the frustration here. 我不确定我是否在这里感到沮丧。 Or to be more precise: what do you think is too slow / should be faster? 或者更确切地说:你觉得什么太慢/应该更快? If I read your data points correctly you're still under 1ms per executed query. 如果我正确读取了您的数据点,则每个执行的查询仍然不到1毫秒。

You might wanna improve your test scenario a bit: 您可能想稍微改进您的测试场景:

  1. Your data model is rather simplistic. 您的数据模型相当简单。 A collection of primitives doesn't make Mongo shine really. 一组原语并没有让Mongo真正发光。 It excels relational databases if you can store aggregates directly instead of joining them together as you would have to with a relational store. 如果您可以直接存储聚合而不是像在关系存储中那样将它们连接在一起,那么它优于关系数据库。

  2. Your access patterns are trivial. 您的访问模式是微不足道的。 findAll(…) is just streaming the data back to the client and is probably quite optimized against a Postgres as well. findAll(…)只是将数据流回客户端,也可能针对Postgres进行了优化。 If you have the indexes set correctly, Postgres and Mongo shouldn't differ too much. 如果您正确设置了索引,Postgres和Mongo不应该有太大差异。 Also the simple range queries do not let Mongo excel really. 此外,简单范围查询不会让Mongo真正出类拔萃。 This essentially all boils down to 1. If you get a more complex data model and the JOINs start to pile up in the relational world you'll see the difference. 这基本上都归结为1.如果你得到一个更复杂的数据模型,并且JOIN开始在关系世界堆积起来,你会看到差异。

  3. You read way to little data. 你读了很少的数据。 30 rows/documents is simply nothing. 30行/文件根本没什么。 To see differences you need to increase the amount of documents / rows to be returned. 要查看差异,您需要增加要返回的文档/行数。 If you do so, make sure you compare apples to apples: with Spring Data MongoDB you get document-to-object mapping, which you don't get with plain JDBC. 如果你这样做,请确保你比较苹果和苹果:使用Spring Data MongoDB,你可以获得文档到对象的映射,这是普通JDBC无法实现的。

There's two conclusions I'd draw: 我得出两个结论:

  1. Anything but the results you see would be a shocking result for Postgres or the relational approach in general. 除了你看到的结果之外,对于Postgres或一般的关系方法来说,这将是一个令人震惊的结果。 MongoDB is a great database, but if it exceeded relational in such a simple case (very simple model, very simple queries, very little data), wouldn't that make relational look like toys? MongoDB是一个很棒的数据库,但是如果它在如此简单的情况下(非常简单的模型,非常简单的查询,非常少的数据)超过关系,那么关联看起来不会像玩具一样吗? They're not. 他们不是。 They just have characteristics that make them a sub-optimal choice in some cases but might even perform better in others. 在某些情况下,它们只具有使其成为次优选择的特性,但在其他情况下甚至可能表现更好。 Performance is one aspect of the decision. 绩效是决策的一个方面。 Ease of getting data in and out of the store is another, and so is scalability. 易于将数据输入和输出存储是另一种方式,可扩展性也是如此。

  2. If you're really up to a store comparison, make sure you compare on the right levels of abstraction. 如果您真的要进行商店比较,请确保在正确的抽象级别上进行比较。 For MongoDB this would probably be the raw driver API vs JDBC on the Postgres side. 对于MongoDB,这可能是Postgres端的原始驱动程序API与JDBC。 If you bring O(R|D)M into the game you're comparing the store + the mapper framework which might distort the results. 如果你将O(R | D)M带入游戏,你就会比较商店+映射器框架,这可能会扭曲结果。

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

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