ルックアップ集約のパフォーマンスが悪い 質問する

ルックアップ集約のパフォーマンスが悪い 質問する

私は2つのコレクションを持っています

投稿:

{
    "_Id": "1",
    "_PostTypeId": "1",
    "_AcceptedAnswerId": "192",
    "_CreationDate": "2012-02-08T20:02:48.790",
    "_Score": "10",
    ...
    "_OwnerUserId": "6",
    ...
},
...

およびユーザー:

{
    "_Id": "1",
    "_Reputation": "101",
    "_CreationDate": "2012-02-08T19:45:13.447",
    "_DisplayName": "Geoff Dalgas",
    ...
    "_AccountId": "2"
},
...

5~15 件の投稿をしたユーザーを見つけたいとします。クエリは次のようになります。

db.posts.aggregate([
    {
        $lookup: {
            from: "users", 
            localField: "_OwnerUserId",
            foreignField: "_AccountId", 
            as: "X"
        }
    },  
    {
        $group: {
            _id: "$X._AccountId", 
            posts: { $sum: 1 }
        }
    },   
    {
        $match : {posts: {$gte: 5, $lte: 15}}
    },  
    {
        $sort: {posts: -1 }
    },
    {
        $project : {posts: 1}
    }
])

動作がひどく遅いです。6,000 人のユーザーと 10,000 件の投稿に対して、応答を得るのに 40 秒以上かかりましたが、リレーショナル データベースでは、ほんの一瞬で応答が得られます。どこに問題があるのでしょうか? 私は mongodb を使い始めたばかりで、このクエリを間違えた可能性があります。

ベストアンサー1

からhttps://docs.mongodb.com/manual/reference/operator/aggregation/lookup/

foreignField は、from コレクション内のドキュメントのフィールドを指定します。$lookupはforeignFieldで等価性マッチを実行します入力ドキュメントの localField に追加します。from コレクション内のドキュメントに foreignField が含まれていない場合、$lookup は一致のために値を null として扱います。

これは他のクエリと同じように実行されます。

_AccountId フィールドにインデックスがない場合、10,000 件の投稿それぞれに対して完全なテーブルスキャン クエリが実行されます。時間の大部分は、このテーブルスキャンに費やされます。

db.users.ensureIndex("_AccountId", 1) 

プロセスが高速化され、10,000 回のテーブル スキャンではなく 10,000 回のインデックス ヒットが実行されます。

おすすめ記事