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

モンゴトリプルコンパウンドインデックス

    収益/tl;dr: インデックスb aの場合、「スキップ」できます およびc 等式または不等式について照会されますが、たとえば、cでのソートについては照会されません。 。

    これはとても良い質問です。残念ながら、これに正式に答える詳細なものは見つかりませんでした。このようなクエリのパフォーマンスはここ数年で向上したと思うので、このトピックに関する古い資料は信用しません。

    インデックスの選択性と、等式、不等式、または並べ替えをクエリするかどうかに依存するため、全体が非常に複雑になります。したがって、explain() はあなたの唯一の友達ですが、私が見つけたものは次のとおりです:

    警告 :今来るのは、実験結果、推論、推測の混合です。私はカイルのアナロジーを過度に伸ばしているかもしれません、そして私は完全に間違っているかもしれません (そして不幸なことに、私のテスト結果は私の推論と大まかに一致しているためです。)

    Aのインデックスを使用できることは明らかです。これは、Aの選択性によっては、確かに非常に役立ちます。 「スキップ」Bは注意が必要な場合とそうでない場合があります。これをカイルの料理本の例と同じように保ちましょう:

    French
        Beef
            ...
        Chicken
            Coq au Vin
            Roasted Chicken
        Lamb
            ...
        ...
    

    「シャトーブリアン」というフランス料理を探すように言われたら、インデックスAを使用できます。 そして、材料がわからないので、Aのすべての料理をスキャンする必要があります 。一方、各カテゴリの料理のリストは、インデックスCで並べ替えられていることを私は知っています。 、したがって、各材料リストで「Cha」で始まる文字列を探すだけで済みます。 50の材料がある場合、1つではなく50のルックアップが必要になりますが、それはすべてのフランス料理をスキャンするよりもはるかに優れています!

    私の実験では、この数はbの個別の値の数よりもはるかに少なかった。 :2を超えることはありませんでした。ただし、これは1つのコレクションでのみテストしたものであり、おそらくbの選択性に関係しています。 -インデックス。

    すべてのフランス料理のアルファベット順のリストを提供するように依頼された場合 しかし、私はトラブルに陥るでしょう 。 Cのインデックス 価値がないので、これらすべてのインデックスリストをマージソートする必要があります。そのためには、すべての要素をスキャンする必要があります。

    これは私のテストに反映されています。ここにいくつかの簡略化された結果があります。元のコレクションには日時、int、文字列が含まれていますが、物事をシンプルにしたかったので、すべてintになりました。

    基本的に、クエリには2つのクラスしかありません。nscannedのクラスです。 <=2*limit 、およびコレクション全体(120kドキュメント)をスキャンする必要があるもの。インデックスは{a, b, c}です。 :

    // fast (range query on c while skipping b)
    > db.Test.find({"a" : 43, "c" : { $lte : 45454 }});
    // slow (sorting)
    > db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "c" : -1});
    > db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "b" : -1}); 
    
    // fast (can sort on c if b included in the query)
    > db.Test.find({"a" : 43, "b" : 7887, "c" : { $lte : 45454 }}).sort({ "c" : -1});
    
    // fast (older tutorials claim this is slow)
    > db.Test.find({"a" : {$gte : 43}, "c" : { $lte : 45454 }});
    

    マイレージは異なります。



    1. キーを削除するにはどうすればよいですか?

    2. 異なる結果を示すMongoDBのfind()メソッドとfindOne()メソッド

    3. Laravel Socket.io接続されていますが、データを受信して​​いません

    4. MongoDB Atlasの概要:パート2