2

我有这个简单的课程:

@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 行。

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

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

为什么?难道我做错了什么?我期待 mongo 更快。(我的应用程序很少使用,只是查找全部。大多数时候我使用过滤器进行排序)

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

肿瘤坏死因子

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

1 回答 1

3

我不确定我是否在这里感到沮丧。或者更准确地说:你认为什么太慢/应该更快?如果我正确读取了您的数据点,那么每次执行查询的时间仍然不到 1 毫秒。

您可能想稍微改进一下测试场景:

  1. 您的数据模型相当简单。一组原语并不能真正让 Mongo 大放异彩。如果您可以直接存储聚合而不是像使用关系存储那样将它们连接在一起,那么它就优于关系数据库。

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

  3. 您读取的数据很少。30 行/文档根本算不了什么。要查看差异,您需要增加要返回的文档/行的数量。如果这样做,请确保将苹果与苹果进行比较:使用 Spring Data MongoDB,您可以获得文档到对象的映射,而使用普通 JDBC 则无法获得。

我会得出两个结论:

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

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

于 2013-06-27T21:21:07.917 回答