У меня есть функция, которая выглядит примерно так:
//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 или лучше извлечь все значения результата в массив и получить значение оттуда?
Один запрос, который возвращает десяток фрагментов данных, почти в 12 раз быстрее, чем 12 запросов, которые возвращают 1 часть данных.
О, НИКОГДА НИКОГДА НИКОГДА не ставьте SQL внутри цикла, он всегда будет приводить к катастрофе.
В зависимости от того, как работает ваше приложение, для каждого запроса может быть открыто новое соединение, это особенно плохо, поскольку каждый сервер БД имеет ограничение на количество подключений. Затем также поймите, что это произойдет для каждого пользователя, поэтому 50 запросов с 5 пользователями, и у вас уже есть 250 запросов в любой момент. Но даже если все запросы имеют только одно соединение, вы накладываете на сервер БД больше X раз, замедляя его на все остальное, на каждой странице, потому что пользователи зацикливают сервер БД на этой странице, и все должны делиться.
Я видел, что в прошлом приложение полностью не работало из-за этого недостатка дизайна, просто не делайте этого.
Я согласен с другими – и я тот, кто разработал и закодировал API-интерфейсы таблиц в Zend Framework, который вы используете!
Функция findDependentRowset()
полезна, если у вас уже есть ссылка на родительскую строку, и вам может потребоваться выборка связанных строк. Эта функция неэффективна, по крайней мере, по сравнению с запросом, соединяющим обе таблицы. Вы не должны вызывать findDependentRowset()
в цикле, когда-либо, если производительность является приоритетом вообще. Вместо этого напишите SQL-запрос, состоящий из JOIN обеих таблиц.
К сожалению, ретроспективно, что цель Zend для их Framework была простотой дизайна, а не производительностью.
Если бы я продолжал работать в Zend, я бы попытался улучшить интерфейс Table с помощью удобного способа выполнения связанных запросов с соответствующими объектами Zend_Db_Table. Решение, реализованное после того, как я покинул проект, состоит в том, чтобы построить объект Select и передать его fetchAll()
, который ужасно уродлив.
В ответ на ваш комментарий я сделал все возможное, чтобы создать решение с учетом набора требований. Мне хорошо, что я сделал. Но Zend является компанией IDE, поэтому, естественно, их ценность заключается в удобстве кодирования, а не во время исполнения. «Быстрая разработка приложений» может означать разработку быстрых приложений или быстрое развитие приложений. Для компании-инструментария это означает последнее.
Определенно получить все и получить из массива.