1

MongoCursor状況によっては、パフォーマンスが非常に遅くなることに直面しました。

$mongoClient = new MongoClient('mongodb://127.0.0.1:27017');
$collection = $mc->mydb->mycollection;

テスト1:

for($i=0; $i<1000; $i++)
{
    $cursor = $collection->find()->limit(2);
    $cursor->next();
}

経過時間: 41.78210 秒 [ 24 オペレーション/秒]

テスト2:

for($i=0; $i<1000; $i++)
{
    $cursor = $collection->find()->limit(1);
    $cursor->next();
}

経過時間: 0.47898 秒 [2,088オペレーション/秒]

テスト3:

for($i=0; $i<1000; $i++)
{
    $cursor = $collection->find()->limit(2)->batchSize(-2);
    $cursor->next();
}

経過時間: 0.65439 秒 [ 1 528 op/s ]

test1では、スクリプトが常に 24 ops/s を実行するかどうlimit(2)かに関係なく;limit(200)

私はそれをテストしました:

  • モンゴ v2.4.5

  • PHP ドライバー 1.4.0dev および 1.5.0dev

  • Debian 6.0.7 および Ubuntu 12.10

これはphpドライバーの問題ですか?

EDIT1:

MongoLog でログを記録したところ、興味深い結果が得られました。

MongoLog::setLevel(MongoLog::ALL);
MongoLog::setModule(MongoLog::IO);

test1: (制限 (N) ここで N > 1)

  • 1375693731.5349 - IO (FINE): 応答を取得中
  • 1375693731.5350 - IO (FINE): カーソル ヘッダーの取得
  • 1375693731.5351 - IO (FINE): カーソル本体の取得
  • 1375693731.5351 - IO (警告): 未完成のカーソル 63182808988603511 を強制終了しています
  • 1375693731.5352 - IO (FINE): 応答を取得中
  • 1375693731.5353 - IO (FINE): カーソルヘッダーを取得しています
  • 1375693731.5726 - IO (FINE): カーソル本体の取得
  • 1375693731.5727 - IO (警告): 未完成のカーソル 63182981334616260 を強制終了しています
  • ...

test2: (制限(1)、制限(0)、制限なし)

  • 1375693866.2663 - IO (FINE): 応答を取得中
  • 1375693866.2663 - IO (FINE): カーソル ヘッダーの取得
  • 1375693866.2663 - IO (FINE): カーソル本体の取得
  • 1375693866.2665 - IO (FINE): 応答を取得中
  • 1375693866.2665 - IO (FINE): カーソル ヘッダーの取得
  • 1375693866.2665 - IO (FINE): カーソル本体の取得
  • ...

クエリを N (N>1) ドライバーで制限するとわかるようにkilling unfinished cursor、次にカーソル本体を取得しようとすると、多くの時間がかかります。

EDIT2:

はい、そのタイミングは 20 個のドキュメントのみのコレクションに関係しますが、20K ドキュメントは limit(0) と noLimit のみに影響し、あなたが言ったようにカーソルを強制終了します。

これは logLevel:5 のログです。何の手がかりもありません。

mongodb.log:制限 (N)

  • 月 8 月 5 日 14:43:55.292 [conn3] クエリ mydb.mycollection cursorid:1002459676459826 ntoreturn:2 ntoskip:0 nscanned:3 keyUpdates:0 ロック (マイクロ) r:84 nreturned:2 reslen:86 0ms
  • 月 8 月 5 日 14:43:55.293 [conn3] killcursors: 1 の 1 が見つかりました
  • 8 月 5 日月曜日 14:43:55。293 [conn3] killcursors keyUpdates:0 0ms
  • 8 月 5 日月曜日 14:43:55。332 [conn3] runQuery と呼ばれる mydb.mycollection {}
  • 月 8 月 5 日 14:43:55.333 [conn3] クエリ mydb.mycollection cursorid:1002631131988423 ntoreturn:2 ntoskip:0 nscanned:3 keyUpdates:0 ロック (マイクロ) r:84 nreturned:2 reslen:86 0ms

mongodb.log:制限 (1)

  • 月 8 月 5 日 14:45:54.899 [conn3] runQuery と呼ばれる mydb.mycollection {}
  • 月 8 月 5 日 14:45:54.899 [conn3] クエリ mydb.mycollection ntoreturn:1 ntoskip:0 nscanned:1 keyUpdates:0 locks(micros) r:39 nreturned:1 reslen:53 0ms
  • 月 8 月 5 日 14:45:54.899 [conn3] runQuery と呼ばれる mydb.mycollection {}
  • 月 8 月 5 日 14:45:54.899 [conn3] クエリ mydb.mycollection ntoreturn:1 ntoskip:0 nscanned:1 keyUpdates:0 locks(micros) r:35 nreturned:1 reslen:53 0ms
4

1 に答える 1

2

これをどのように実行しているのか、私のコレクションにいくつのアイテムがあるのか​​はわかりませんが、アイテムの数に関係なく、3 つのテストはすべて 0.102 ~ 0.112 秒かかります。走るよりずっと速い。これは、PHP 5.4 およびドライバー バージョン 1.5.0dev を使用しています。

「Kill​​ing unfinished cursor」メッセージは、カーソルが示す結果セットに属するすべてのデータを読み取っていないためです。メッセージも表示されるため、コレクションに20kではなく20個のアイテムしかない状態でテストしたと思います。

デフォルトでは、MongoDB から読み取られる最初のバッチは 101 ドキュメントです。したがって、結果セットがそれよりも小さい場合、カーソルはありません。

limit(1)そしてlimit(n)、 「多くの結果を出してからカーソルを閉じるn < 0」という意味で特別です。abs(n)

limit(0)制限が与えられていないということは、「デフォルトのバッチをください」という意味であり、最初の結果は 101 ドキュメントです。これについては、http://drck.me/mongocur-9f8で詳しく書いています。

カーソルが強制終了された後、どこで 37 ミリ秒の速度低下が発生するかについては、まだ謎です。おそらく、mongodb.logファイルに洞察があるかどうかを確認できますか? (その情報が表示されたら、回答を再度更新します)

于 2013-08-02T14:37:02.433 に答える