最初のクエリで観察されたパフォーマンスの問題は、次の問題のいずれかである可能性があります (大まかな順序で)。
1) アプリケーション/Web サービスには、最初の要求で初期化するためのオーバーヘッドがあります (つまり、メモリの割り当て、接続プールの設定、DNS の解決など)。
2) リクエストしたインデックスまたはデータはまだメモリにないため、ロードする必要があります。
3)クエリ オプティマイザーは、クエリ パターンのプラン実行を比較しているため、最初の要求で実行するのに少し時間がかかる場合があります。
シェルを介してクエリをテストし、オーバーヘッドが MongoDB または Web サービスに関連しているかどうかを分離することは非常に役立ちますmongo
(両方のタイミングをとるのではなく)。
以下は、MongoDB に関する注意事項です。
キャッシング
MongoDB には、メモリ内のドキュメントの「キャッシュ」時間がありません。ディスク I/O にメモリ マップ ファイルを使用し、メモリ内のドキュメントは、アクティブなクエリ (最近読み込んだドキュメント/インデックス) と使用可能なメモリに基づいています。オペレーティング システムの仮想メモリ マネージャは、キャッシングを担当し、通常、Least-Recently Used (LRU) アルゴリズムに従って、メモリからスワップ アウトするページを決定します。
メモリ使用量
予想される動作は、時間の経過とともに MongoDB が成長し、すべての空きメモリを使用してアクティブな作業データ セットを格納することです。
提供された数値を見ると(そしてそれが唯一db.stats()
のデータベースであると仮定して)、データベースのサイズは現在約1Gbであるように見えるため、次の場合を除き、すべてを合計RAM 10Gb以内に保つことができるはずです。
- メモリをめぐって競合する他のプロセスがあります
- サーバーを再起動しましたが
mongod
、それらのドキュメント/インデックスはまだリクエストされていません
MongoDB 2.2 にはtouch
、サーバーの再起動後にインデックスまたはドキュメントをメモリにロードするために使用できる新しいコマンドがあります。これは、最初の起動時にサーバーを「ウォームアップ」するためにのみ使用する必要があります。そうしないと、実際の「アクティブな」データをメモリから追い出すのに役に立たない可能性があります。
たとえば、Linux システムでは、次のtop
コマンドを使用すると、次のように表示されます。
- 仮想バイト/VSIZE は、データベース全体のサイズになる傾向があります
- サーバーで他のプロセスが実行されていない場合、常駐バイト/RSIZE がマシンの合計メモリになります (これにはファイル システム キャッシュの内容が含まれます)。
mongod
スワップを使用しないでください (ファイルがメモリマップされているため)
このmongostat
ツールを使用すると、mongod
アクティビティをすばやく確認できます。さらに便利なことに、MMSなどのサービスを使用して、メトリックを経時的に監視することもできます。
クエリ オプティマイザー
MongoDBクエリ オプティマイザーは、約 1,000 回の書き込み操作ごとにクエリ パターンのプラン実行を比較し、次にオプティマイザーが実行されるまで、またはexplain()
そのクエリで を明示的に呼び出すまで、「勝った」クエリ プランをキャッシュします。
これは簡単にテストできるはずです。mongo
シェルでクエリを実行.explain()
し、ミリ秒のタイミングと、スキャンされたインデックス エントリとドキュメントの数を調べます。Explain() のタイミングは、プランを比較するコストが含まれているため、クエリの実行に実際にかかる時間ではありません。通常の実行ははるかに高速で、ログで遅いクエリを探すことができmongod
ます。
デフォルトでは、MongoDB は 100 ミリ秒より遅いすべてのクエリをログに記録するため、これは最適化するクエリを探す良い出発点となります。--slowms
config オプションまたはコマンドを使用して、slow ms 値を調整できDatabase Profiler
ます。
MongoDB のドキュメントをさらに読む: