performance - MongoDB + SpringData 查询非常慢

标签 performance mongodb spring-data

我有这个简单的类(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
}

我有另一个具有相同属性但用 @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 且价格 <=9000 且里程表 >=1 且里程表 <= 40000 将花费:Mongo:约 7000 毫秒,PostgreSQL 约 7200 毫秒

为什么?我做错了什么吗? 我期待 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 毫秒。

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

  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 引入游戏中,您将比较存储 + 映射器框架,这可能会扭曲结果。

关于performance - MongoDB + SpringData 查询非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13062897/

相关文章:

java - 带有 LIKE 和 IgnoreCase 的 Spring Data CrudRepository @Query

spring - elasticSearch从其他表索引

c# - 为什么 C# 运行速度比 C++ 快?

performance - GPU上整数和按位运算的性能

php - 使用 Sonata 和 MongoDB 更新 Symfony 中的许多引用时出现问题

mongodb - 如何查询所有子文档

java - Hibernate - SQL 很快,但查询仍然很慢

c++ - 在 C++ 中为 Matlab 准备矩阵

node.js - 在 mongodb 中保存聊天消息的最佳方法?

java - Spring Repository Rest Resource - 不保存子对象的问题