2013-03-09 13 views
9

.explain()の出力をMongoDBクエリで使用すると、nnscannedの違いを見て、フルコレクションスキャンが実行されたかどうかを判断できます。または索引が使用されている場合。 The docs状態MongoDBでフルコレクションスキャンが行われたかどうかを判断する方法

あなたがnnscannedはできるだけ値の近いものにしたいです。

Kyle Banker's excellent book MongoDB in Actionは非常に似たような言葉:

は、一般的に言えば、あなたはnnscannedの値はできるだけ一緒に近いことにしたいです。コレクションスキャンを実行する場合、これはほとんどありません。

これらのステートメントのどちらも明らかに、nnscannedを比較することはありません。差異に占める割合は、通常、フルコレクションスキャン(10%、20%、30%+)を推測していますか?フルコレクションのスキャンが完了したかどうかを確認する他の方法はありますか?

答えて

6

通常、フルコレクションスキャンの割合はどの程度の割合 - 10%、20%、30%+?

これは本当に大変重要なことではありませんが、平均的な検索では200%のパフォーマンス低下が見られる可能性があります。そう、はい、あなたはそれに気付くでしょう。これは他のデータベースのようなものです。

フルコレクションのスキャンが完了しているかどうかを確認する他の方法はありますか?

あなたはそれがしようとしたとき、それは例外がスローされます。その場合には全表スキャンを、決してしないように指示フラグでのMongoDBを開始することができます:最良の方法はただにしているがhttp://docs.mongodb.org/manual/reference/mongod/#cmdoption-mongod--notablescan

ここでexplainを使用すると、クエリでインデックスが使用されず、ディスクまたはメモリからコレクション全体をスキャンする必要があることがわかります。

+1

からの結果をマージするための
-SHARD_MERGEを文書を取得するためしかし、それは可能クエリがインデックスを使用するためのものであり、まだ完全なコレクションスキャンを実行しますか? – br3w5

+2

@ssbrewsterそうではありませんが、索引の実行には別のことが必要です。索引を使用し、正しい方法でインデックスを使用することは別の2つの方法です – Sammaye

+0

これはインデックスが結果をソートするためにのみ使用されますか? – br3w5

1

確定的な答えは、explain()出力の最初の行です。

カーソルタイプが "BasicCursor"と表示されている場合は、単純なコレクションスキャンでした。

それ以外の場合は、使用されたインデックスのタイプとインデックスの名前、つまりインデックスが表示されます。 "BtreeCursor id"

同じドキュメントについては、http://docs.mongodb.org/manual/reference/explain/#explain-output-fields-coreを参照してください。

+0

しかし、私が上記で尋ねたように、索引が結果のソートにのみ使用される場合、コレクションのスキャンはまだ発生しますか? – br3w5

+2

@ssbrewsterもしあなたが 'b'のインデックスを作成し、それから' db.col.find({a:1})。sort({b:1}); '完全なテーブルスキャンはしませんが、ええ – Sammaye

+0

@サマエさんは感謝しています...そしてnscanned物件に戻ってみると、もし私が2人の30%-40%の違いを見ているなら、フルコレクションのスキャンが完了したと言っても大丈夫だと思います。コレクション上でcount()を実行し、nscannedと比較するだけでこれを検証できますか? – br3w5

24

上記の回答は完全ではありません。

インデックスはソートに使用されますが、一致基準を支援できないコレクションスキャンも実行されます。そのような場合、検索基準に一致するドキュメントを見つけるために、すべてのドキュメントが(インデックス順に)スキャンされます。もう1つの可能性は、インデックスが1つまたは複数の検索基準に従ってドキュメントのサブセットを絞り込むことができるが、完全な検索基準の一致を見つけるためにこのサブセットのドキュメントをスキャンする必要がある部分コレクションスキャンがある可能性があることです。

このような状況では、ExplainはBasicCursorではなくインデックスが使用されていることを示します。したがって、説明中のBasicCursorの存在がコレクションスキャンが実行されていることを示していますが、それがないことはコレクションスキャンが実行されなかったことを意味しません。

また、--notablescanを使用しても、インデックスがソートに使用される場所には役立ちません。クエリは、インデックスが使用されていない場合にのみ例外を発生させるためです。索引が一致またはソートに使用されたかどうかは検索されません。

コレクションのスキャンが実行されたかどうかを判断する唯一確実な方法は、インデックスキーをクエリの一致条件と比較することです。クエリオプティマイザによって選択されたインデックス(および説明に図示)がクエリ一致基準(すなわち、異なるフィールド)に応答できない場合、コレクションスキャンが必要です。

+0

MongoDBは索引ソートでコレクションスキャンを実行しません。索引が存在しない場合を除き、mongodbは索引内の文書の順序を返します。コレクションスキャン、メモリー内のscanandorder、そしてそれらの文書を返します。 – Sammaye

+0

あなたが実際にscanandorder trueを持っている時間の99%を見つけることができます。これは、インデックスがソートに使用されていないことを意味します。 – Sammaye

+3

あなたは、ソートがfindと一致する状況だけを考えているようです。ソートのみをサポートするインデックスがあり、検索とのマッチングを行う場合、インデックスはソートに使用されます(インデックスはソート順を取得するために実行されます)が、スキャン/試合。たとえば、{a:1}の索引ではなく、db.test.find({b:1})のfind文を使用して、書式{a:1、b:1}のドキュメントを取得します。 。 bにインデックスがない場合、{a:1}インデックスがソートに使用されますが、コレクションは引き続きスキャンされます。 – Matt

0

厳密には、カーソルが基本カーソルである場合にのみフルテーブルスキャンが実行されたようです。

btreeカーソルがある場合、ソートに使用されているbtreeインデックスを使用してレコードを検索するために、完全なテーブルスキャンが行われている可能性があります。ただし、説明の出力を見れば、レコードの数を数えずに既存のインデックスを調べることなく、完全なテーブルスキャンであることを確かめることができます。

質問の文脈では、クエリが効率的でなく、よりよいインデックスが必要であるか、または暗示すべきであるかどうかは明らかです。

0

あなたは(MongoDBのドキュメントから)の説明の段階を確認することができます。

ステージは、操作の記述です。例えばスキャンインデックスキー
-FETCHため-IXSCAN

収集スキャンの-COLLSCAN


破片

関連する問題