12

単一の巨大なコレクションと複数の小さなコレクションの2つのシナリオをテストしたところ、クエリ中のパフォーマンスに大きな違いがあることがわかりました。これが私がしたことです。

ケース1:10種類の商品について1,000万件のレコードを含む商品コレクションを作成し、この中に商品タイプごとに正確に100万件のレコードを作成し、ProductTypeにインデックスを作成しました。条件ProductType=1、ProductPrice> 100、limit(10)でサンプルクエリを実行して、ProductType = 1の10レコードを返し、価格が100を超える場合、コレクションに価格の製品が多数ある場合、約35ミリ秒かかりました。は100を超えており、ProductType = 1の価格が100を超える製品の数が非常に少ない場合、同じクエリに約8000ミリ秒(8秒)かかりました。

ケース2:ProductTypeごとに10個の異なるProductテーブルを作成し、それぞれに100万件のレコードが含まれています。productType 1のレコードを含むコレクション1で、条件ProductPrice> 100およびlimit(10)を使用して同じサンプルクエリを実行し、価格が100を超える製品のレコードを10個返すと、コレクションにロットがある場合、約2.5ミリ秒かかりました。価格が100を超える製品の数であり、価格が100を超える製品の数が非常に少ない場合、同じクエリに約1500ミリ秒(1.5秒)かかりました。

では、なぜそれほど大きな違いがあるのでしょうか。ケース1とケース2の唯一の違いは、1つの巨大なコレクションと複数の小さなコレクションですが、最初のケースでは1つの巨大なコレクションでProductTypeのインデックスを作成しました。パフォーマンスの違いは、最初のケースのインデックスが原因だと思います。最初のケースではそのインデックスが必要です。そうしないと、パフォーマンスがさらに低下します。最初のケースではインデックスが原因でパフォーマンスが低下すると予想していましたが、最初のケースでは約10倍の大きな違いは予想していませんでした。

つまり、1つの大きなコレクションと複数の小さなコレクションでは8000ミリ秒と1500ミリ秒です。なんで?

4

1 に答える 1

16

コレクションを分離すると、実際のオーバーヘッドなしで無料のインデックスが得られます。インデックススキャンにはオーバーヘッドがあります。特に、インデックスがスキャンする結果の数を減らすのに実際に役立っていない場合(インデックスに100万件の結果があるが、すべてをスキャンして検査する必要がある場合は、それはあなたをあまり助けないでしょう)。

要するに、それらを分離することは有効な最適化ですが、実際にそのルートを取ることを決定する前に、クエリに対してインデックスを改善する必要があります。これは、抜本的な対策と考えられます(この場合、製品価格のインデックスがより役立つ可能性があります) 。

Explain()を使用すると、クエリがどのように機能するかを理解するのに役立ちます。いくつかの基本事項は次のとおりです。理想的には、nscannedとnの比率を低くする必要があります。通常、scanAndOrder = trueは必要なく、BasicCursorも必要ありません(これは、インデックスをまったく使用していないことを意味します)。

于 2012-07-17T01:40:43.383 に答える