sql >> データベース >  >> NoSQL >> MongoDB

Mongoクエリには時間がかかります。どうすればもっと速くできますか?

    インデックスは、クエリのすべての部分(等式部分、並べ替え部分、および範囲部分)をカバーする必要があります。これは、一般的なfind()では クエリでは、MongoDBは1つのインデックスのみを使用します。たとえば、通常、等式部分に1つのインデックスを使用せず、並べ替え部分に別のインデックスを使用します。

    一般に、インデックス内のフィールドのシーケンスは、 equality-> sort-> rangeのパターンに従う必要があります。 。

    これについては、MongoDB複合インデックスの最適化 で詳しく説明されています。 。

    クエリの場合、等価部分はtag:..., letterId:...です。 並べ替え部分はemailId:-1です。 。クエリに範囲の部分はありません。

    このパターンを使用すると、必要な複合インデックスは次のようになります。

    db.test.createIndex({tag:1, letterId:1, emailId:-1})
    

    このインデックスを使用して、パフォーマンスがどれだけ向上するかを確認してみましょう。

    テストデータ

    インデックスの適合性を確認するために、mgeneratejs を使用して100万レコードをテストデータベースに挿入しました。 、テンプレートを使用してランダムなドキュメントを作成するためのツールです。

    あなたの例に基づいて、mgeneratejs 私が使用しているテンプレートは次のとおりです:

    $ cat template.json
    {
      "emailId": "$hash",
      "email": "$email",
      "letterId": "$hash",
      "sendedFrom": "$email",
      "resultMsg": "$word",
      "owner": "$name",
      "created": "$date",
      "result": "$bool",
      "tag": "$word",
      "tryNum": {"$integer": {"min": 0, "max": 1e3}},
      "clickHash": "$word",
      "links": {"$array": {"of": "$url", "number": {"$integer": {"min": 1, "max": 5}}}}
    }
    

    100万のランダムなドキュメントをMongoDBにインポートしました:

    $ mgeneratejs template.json -n 1000000 | mongoimport -d test -c test
    

    テスト1:最適でないインデックス

    次に、使用しているインデックスを作成し、存在しないドキュメントを見つけて、このインデックスのみを含むコレクションを使用してクエリを10回実行しました。

    > db.test.createIndex({emailId: 1, letterId: 1, result: 1, owner: 1, tag: 1, clickHash: 1})
    
    > db.test.find({"tag" : "xyz", "letterId" : "abc"}).sort({emailId: -1}).limit(1)
    Fetched 0 record(s) in 3069ms
    Fetched 0 record(s) in 2924ms
    Fetched 0 record(s) in 2923ms
    Fetched 0 record(s) in 3013ms
    Fetched 0 record(s) in 2917ms
    Fetched 0 record(s) in 2961ms
    Fetched 0 record(s) in 2882ms
    Fetched 0 record(s) in 2870ms
    Fetched 0 record(s) in 2969ms
    Fetched 0 record(s) in 2863ms
    

    そのため、そのインデックスを使用すると、クエリの応答時間は長くなく、ほとんどの実行は3秒近くになります。

    テスト2:同等性->並べ替え->範囲インデックス

    最適な等式->並べ替え->範囲を追加する インデックス:

    > db.test.createIndex({tag:1, letterId:1, emailId:-1})
    
    > db.test.find({"tag" : "xyz", "letterId" : "abc"}).sort({emailId: -1}).limit(1)
    Fetched 0 record(s) in 2ms
    Fetched 0 record(s) in 1ms
    Fetched 0 record(s) in 1ms
    Fetched 0 record(s) in 1ms
    Fetched 0 record(s) in 1ms
    Fetched 0 record(s) in 1ms
    Fetched 0 record(s) in 1ms
    Fetched 0 record(s) in 1ms
    Fetched 0 record(s) in 1ms
    Fetched 0 record(s) in 3ms
    

    対照的に、最適なインデックスを使用すると、パフォーマンスが大幅に向上しました。 3ミリ秒を超えて返されるクエリはなく、ほとんどの場合1ミリ秒で返されます。



    1. PHPMongoDBに再帰的にカテゴリを入力する

    2. 存在しないドキュメントのみをインポートするにはどうすればよいですか?

    3. お誕生日おめでとうApacheHBase! 10年間の回復力、安定性、パフォーマンス

    4. Mongodbであいまい検索しますか?