Вызывает ли это проблему с производительностью MongoDB (при выполнении «лимита» на стороне клиента путем «ломания» «курсора»)? - PullRequest
0 голосов
/ 09 мая 2011

Хотя это не имеет ничего общего с PHP, я использую PHP в следующих примерах.

Допустим, это «нормальный» способ ограничения результатов.

$db->users->find()->limit(10);

ЭтоВозможно, это самый быстрый способ, но здесь есть некоторые ограничения ... В следующем примере я отфильтрую все строки, в которых значение сохранения для определенного столбца равно предыдущему:

$cursor = $db->users->find();
$prev = null;
$results = array();
foreach ($cursor as $row) {
    if ($row['coll'] != $prev['coll']) {
        $results[] = $row;
        $prev = $row;
    }
}

Но вы все равно хотите ограничить результаты до 10, конечно.Таким образом, вы можете использовать следующее:

$cursor = $db->users->find();
$prev = null;
$results = array();
foreach ($cursor as $row) {
    if ($row['coll'] != $prev['coll']) {
        $results[] = $row;
        if (count($results) == 10) break;
        $prev = $row;
    }
}

Объяснение: поскольку $cursor на самом деле не загружает результаты из базы данных, break в foreach -loop будет limit так жеlimit(...) -функция работает.

Просто точно, действительно ли это работает, как я говорю, или есть какие-то проблемы с производительностью, о которых я не знаю?

Спасибо большоемного, Тим

1 Ответ

1 голос
/ 09 мая 2011

Объяснение: поскольку курсор $ на самом деле не загружает результаты из базы данных, разрыв цикла foreach ограничит его так же, как и функция limit (...).

Это не на 100% верно.

Когда вы делаете foreach, вы в основном выпускаете серию hasNext / getNextэто перебирает данные.

Однако под этим уровнем драйвер фактически запрашивает и получает пакеты результатов.Когда вы делаете getNext, драйвер будет беспрепятственно получать следующую партию для вас.

Вы можете контролировать размер партии.Детали в документации должны помочь уточнить, что происходит .

Во втором примере, если вы дойдете до 10, а затем break, есть два побочных эффекта:

  1. Курсор остается открытым на сервере (время ожидания через 10 минут, как правило, не имеет большого значения).
  2. Возможно, в $cursor кэшировано больше данных.Этот кэш исчезнет, ​​когда $cursor выйдет из области видимости.

В большинстве случаев эти побочные эффекты "не имеют большого значения".Но если вы выполняете большую часть этой обработки за один процесс, вам понадобится «очистить», чтобы избежать зависания курсоров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...