【问题标题】:MongoDB + SpringData Query very slowMongoDB + SpringData 查询很慢
【发布时间】:2013-06-28 05:26:14
【问题描述】:

我有这个简单的课程:

@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

  • 10000 次 findAll 类型的查询,其中价格 >= 1 且价格 =1 且里程表

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

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

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

【问题讨论】:

  • 您的收藏中有多少文档?你在使用索引吗?您能否提供用于访问文档的查询?
  • 嗨,Thomas,我正在测试大约 30 条记录。是的,我在 Mongo 中使用索引,完全覆盖查询中的字段。不知道如何获取查询,因为我是从 Web 界面动态构建的。我将在原始帖子中添加更多代码

标签: performance mongodb spring-data


【解决方案1】:

我不确定我是否感到沮丧。或者更准确地说:你认为什么太慢/应该更快?如果我正确读取了您的数据点,那么每次执行查询的时间仍然不到 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 带入游戏,您就是在比较商店 + 映射器框架,这可能会扭曲结果。

【讨论】:

    猜你喜欢
    • 2017-01-18
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    相关资源
    最近更新 更多