MongoDB + SpringData查询非常慢

时间:2012-10-25 06:34:28

标签: performance mongodb spring-data

我有这个简单的课程:

@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
}

我有另一个具有相同属性但使用@Entity注释的类。

它们分别存储在MongoDB和PostgreSQL中。

我正在使用Spring Data JPA for PostgreSQL和Spring Data MongoDB ... for mongo。

两个数据库都包含相同的数据,30行。

  • 类型为findAll的10000个查询将花费:Mongo~8000-9000ms和PostgreSQL~10000-11000ms

  • 类型为findAll的10000个查询,其中价格> = 1且价格< = 9000且里程表> = 1且里程表< = 40000将花费:Mongo:~7000ms和PostgreSQL~7200ms

为什么?我做错了吗?我期待mongo更快。 (我的应用程序很少使用我只是找到所有。大多数时候我使用过滤器进行排序)

两台服务器都在FreeBSD 9虚拟机中运行。我在另一台运行CentOS 6.3的虚拟机上测试了这个。类似的结果+ -100ms。

TNX

///更多解释代码(我的过滤器构建器将仅包含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;
}

1 个答案:

答案 0 :(得分:3)

我不确定我是否感到沮丧。或者更确切地说:你觉得什么太慢/应该更快?如果我正确读取了您的数据点,则每个执行的查询仍然不到1毫秒。

您可能想稍微改善您的测试方案:

  1. 您的数据模型相当简单。基元的集合并不能让Mongo真正发光。如果您可以直接存储聚合而不是像关联商店那样将它们连接在一起,那么它优于关系数据库。

  2. 您的访问模式非常简单。 findAll(…)只是将数据流回客户端,并且可能也针对Postgres进行了优化。如果您正确设置了索引,Postgres和Mongo不应该有太大差异。此外,简单范围查询不会让Mongo真正出类拔萃。这基本上都归结为1.如果你得到一个更复杂的数据模型,并且JOIN开始在关系世界堆积起来,你就会看到差异。

  3. 您读到的数据很少。 30行/文件根本就没有。要查看差异,您需要增加要返回的文档/行数。如果你这样做,请确保你比较苹果与苹果:使用Spring Data MongoDB,你得到文档到对象的映射,这是普通的JDBC无法实现的。

  4. 我得出两个结论:

    1. 除了你看到的结果之外,对于Postgres或一般的关系方法来说,这将是一个令人震惊的结果。 MongoDB是一个很棒的数据库,但是如果它在如此简单的情况下(非常简单的模型,非常简单的查询,非常少的数据)超过关系,那么关联看起来不会像玩具一样吗?他们不是。在某些情况下,它们只具有使其成为次优选择的特性,但在其他情况下甚至可能表现更好。性能是决定的一个方面。易于将数据输入和输出存储是另一种方式,可扩展性也是如此。

    2. 如果您真的要进行商店比较,请确保比较正确的抽象级别。对于MongoDB,这可能是Postgres端的原始驱动程序API与JDBC。如果你把O(R | D)M带入游戏,你就会比较商店+映射器框架,这可能会扭曲结果。