PHP - запросить одно значение за одну итерацию или получить все при запуске и извлечь из массива?

У меня есть функция, которая выглядит примерно так:

//iteration over scales
foreach ($surveyScales as $scale)
{
    $surveyItems = $scale->findDependentRowset('SurveyItems');

    //nested iteration over items in scale
    foreach ($surveyItems as $item)
    {
        //retrieve a single value from a result table and do some stuff
        //depending on certain params from $item / $scale
    }
}

ВОПРОС : лучше ли делать db-запрос для каждого отдельного значения внутри внутреннего foreach или лучше выбрать все результирующие значения в массив и получить их оттуда?

10.12.2008 17:03:49
3 ОТВЕТА
РЕШЕНИЕ

Один запрос, который возвращает дюжину фрагментов данных, почти в 12 раз быстрее, чем 12 запросов, которые возвращают 1 фрагмент данных.

О, и НИКОГДА НИКОГДА НЕ ЗАДАВАЙТЕ SQL в цикле, это всегда приведет к катастрофе.

В зависимости от того, как работает ваше приложение, новое соединение может быть открыто для каждого запроса, это особенно плохо, так как каждый сервер БД имеет ограничение на количество соединений. Затем также поймите, что это произойдет для каждого пользователя, так что 50 запросов с 5 пользователями, и у вас уже есть 250 запросов в любой момент. Но даже если все запросы разделяют только одно соединение, вы платите серверу БД X раз больше, замедляя его для всего остального, для каждой страницы, потому что пользователи загружают сервер БД на этой странице, и каждый должен делиться им.

Я видел сбой всего приложения в прошлом из-за этого недостатка дизайна, просто не делайте этого.

18
10.12.2008 17:35:05
Я бы сказал, что запрос, извлекающий x строк, более чем в x раз быстрее, чем x запрашивает каждую строку. Чем больше строк, тем больше разница.
Tomalak 10.12.2008 17:11:12
если бы вы могли уточнить немного о части бедствия, ответ мог бы стать принятым. благодарю вас!
markus 10.12.2008 17:18:11
Чтобы уточнить, о чем он говорит: вы попадете в базу данных 12 раз. Это (по крайней мере) дюжина вызовов PHP-функций, возможно, 12
user42092 10.12.2008 17:26:46
Да, кошмар производительности, который становится экспоненциально хуже, чем больше вы зацикливаетесь.
TravisO 10.12.2008 17:36:05
Точно. Вы можете не заметить это с 10 или 20 строками, но с увеличением оно будет экспоненциально медленнее, и это предполагает, что он не начнет взаимодействовать с такими вещами, как ограничения размера кэша ...
user42092 10.12.2008 17:39:25

Определенно получить все и получить из массива.

1
10.12.2008 17:07:26

Я согласен с остальными - и я тот, кто разработал и кодировал API табличных отношений в Zend Framework, который вы используете!

Это findDependentRowset()полезно, если у вас уже есть ссылка на родительскую строку, и вам может потребоваться получить связанные строки. Эта функция неэффективна по сравнению с запросом, объединяющим обе таблицы. Вы findDependentRowset()никогда не должны вызывать цикл, если производительность вообще является приоритетом. Вместо этого напишите SQL-запрос, состоящий из JOIN обеих таблиц.

К сожалению, в ретроспективе целью Zend для их Framework была простота дизайна, а не производительность.

Если бы я продолжал работать в Zend, я бы попытался улучшить интерфейс Table с помощью удобного способа выполнять объединенные запросы к связанным объектам Zend_Db_Table. Решение, реализованное после того, как я покинул проект, состоит в том, чтобы создать объект Select и передать его fetchAll(), что ужасно уродливо.

изменить: в ответ на ваш комментарий, я сделал все возможное, чтобы создать решение с учетом набора требований. Я прекрасно себя чувствую из-за того, что сделал. Но Zend - компания-разработчик IDE-инструментов, поэтому их ценность заключается в удобстве кодирования, а не в производительности во время выполнения. «Быстрая разработка приложений» может означать разработку быстрых приложений или быструю разработку приложений. Для компании, занимающейся инструментами, это означает последнее.

7
10.12.2008 17:54:11
Вы критикуете свою собственную работу :) Вам не нравится Zend Framework в наше время или это просто особая проблема, которая кажется вам безобразной? Я спрашиваю, потому что звучит так, как будто вы много знаете о ZF, и если кому-то, кто это знает, это совсем не нравится ... хорошо.
markus 10.12.2008 17:32:17
RAD никогда не означает, что приложение выполняется быстро, это всегда означает, что вы можете создавать приложения с меньшими усилиями.
TravisO 11.12.2008 23:25:12