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 にそれぞれ格納されます。

PostgreSQL には Spring Data JPA を、mongo には Spring Data MongoDB を使用しています。

両方のデータベースには、同じデータ (30 行) が含まれています。

  • findAll タイプの 10000 クエリのコスト: Mongo ~8000-9000ms および PostgreSQL ~10000-11000ms

  • price >= 1 and price <=9000 and odometer >=1 and odometer <= 40000 であるタイプ findAll の 10000 クエリのコスト: Mongo: ~7000ms および PostgreSQL ~7200ms

なぜ?私は何か間違ったことをしていますか?私はmongoがはるかに速いと思っていました。(私のアプリケーションでは、すべてを検索することはめったにありません。ほとんどの場合、並べ替えにフィルターを使用します)

どちらのサーバーも FreeBSD 9 仮想マシンで実行されています。CentOS 6.3 を搭載した別の VM でこれをテストしました。同様の結果 +-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;
}
4

1 に答える 1

3

ここでフラストレーションを感じるかどうかはわかりません。または、より正確に言うと、何が遅すぎると思いますか / より速くする必要がありますか? データ ポイントを正しく読み取った場合でも、実行されたクエリごとに 1 ミリ秒未満です。

テストシナリオを少し改善したいかもしれません:

  1. あなたのデータモデルはかなり単純です。プリミティブのコレクションは、Mongo を真に輝かせるものではありません。リレーショナル ストアのように集計を結合するのではなく、集計を直接格納できる場合は、リレーショナル データベースよりも優れています。

  2. アクセスパターンは簡単です。 findAll(…)クライアントにデータをストリーミングしているだけで、おそらく Postgres に対しても非常に最適化されています。インデックスが正しく設定されていれば、Postgres と Mongo はあまり変わらないはずです。また、単純な範囲クエリでは、Mongo が実際に優れているわけではありません。これは基本的にすべて 1 に要約されます。より複雑なデータ モデルを取得し、リレーショナルの世界で JOIN が積み重なっていくと、違いがわかります。

  3. あなたはほとんどデータを読んでいません。30行/ドキュメントはまったくありません。違いを確認するには、返されるドキュメント/行の量を増やす必要があります。そうする場合は、リンゴとリンゴを比較してください。Spring Data MongoDB では、プレーンな JDBC では得られないドキュメントからオブジェクトへのマッピングが得られます。

私が導き出す結論は2つあります。

  1. 表示される結果以外は、Postgres または一般的なリレーショナル アプローチにとって衝撃的な結果になります。MongoDB は優れたデータベースですが、このような単純なケース (非常に単純なモデル、非常に単純なクエリ、非常に少ないデータ) でリレーショナルを超えるとしたら、リレーショナルはおもちゃのように見えませんか? そうではありません。それらには、場合によっては次善の選択となる特性がありますが、他の場合にはより優れたパフォーマンスを発揮する可能性さえあります. パフォーマンスは決定の1 つの側面です。ストアへのデータの出し入れの容易さは別のものであり、スケーラビリティも同様です。

  2. ストアの比較が得意な場合は、適切なレベルの抽象化で比較してください。MongoDB の場合、これはおそらく未加工のドライバー API と Postgres 側の JDBC になります。O(R|D)M をゲームに持ち込むと、ストアとマッパー フレームワークを比較することになり、結果が歪む可能性があります。

于 2013-06-27T21:21:07.917 に答える