22

MongoDB を使用して最初のアプリを作成していました。フィールドのインデックスを作成し、$regex パラメータを使用して検索クエリを試行し、シェルで起動しました

> db.foo.find({A:{$regex:'BLABLA!25500[0-9]'}}).explain()
{
        "cursor" : "BtreeCursor A_1 multi",
        "nscanned" : 500001,
        "nscannedObjects" : 10,
        "n" : 10,
        "millis" : 956,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
                "A" : [
                        [
                                "",
                                {

                                }
                        ],
                        [
                                /BLABLA!25500[0-9]/,
                                /BLABLA!25500[0-9]/
                        ]
                ]
        }
}

同じクエリを起動しているが、コレクションにインデックスがない場合、パフォーマンスがはるかに優れているため、非常に奇妙です。

> db.foo.find({A:{$regex:'BLABLA!25500[0-9]'}}).explain()
{
        "cursor" : "BasicCursor",
        "nscanned" : 500002,
        "nscannedObjects" : 500002,
        "n" : 10,
        "millis" : 531,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {

        }
}

明らかに、正規表現を使用せずにインデックスを使用してフィールドを検索する方がはるかに高速です(つまり、定数フィールドを使用してドキュメントを検索する)が、そのような動作の理由に本当に興味があります。

4

1 に答える 1

13

ここでパフォーマンスが異なる理由は、インデックスが有効な場合、クエリがインデックスをトラバースし (メモリにロード)、一致するドキュメントをロードしてメモリに返す必要があるためです。プレフィックス クエリを使用していないため、インデックス内のすべての値がスキャンされ、正規表現に対してテストされます。あまり効率的ではありません。

インデックスを削除すると、テーブルスキャンを実行して正規表現を照合するだけです-基本的に、最初のものから少し単純化しました。

対象となるインデックス クエリの場合は、インデックス付きバージョンをより高速に作成できる可能性があります。また、これが複合インデックスであり、それを別のフィールドの条件と組み合わせる必要がある場合も、より高速になる可能性があります。

プレフィックス クエリを使用する場合、インデックスを使用するだけではなく、インデックスを効率的に使用することが重要です。したがって、実際のパフォーマンスの向上が見られます。

于 2012-07-06T20:04:57.800 に答える