PHP - запросить одно значение за одну итерацию или получить все при запуске и извлечь из массива? - PullRequest
7 голосов
/ 10 декабря 2008

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

//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
    }
}

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

Ответы [ 3 ]

18 голосов
/ 10 декабря 2008

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

О, и НИКОГДА НИКОГДА не помещайте SQL в цикл, это всегда приведет к катастрофе.

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

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

7 голосов
/ 10 декабря 2008

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

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

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

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

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

1 голос
/ 10 декабря 2008

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

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