Nastradamus
@Nastradamus

Необъяснимое линейное увеличение времени SELECT к базе MySQL при одинаковых запросах в цикле?

Добрый день! Столкнулись с очень странной проблемой.

К сожалению, куски кода привести не могу. Но постараюсь описать суть.

Может кто сталкивался с проблемой и по моей информации будет понятно что мы делаем не так.


Имеем PHP 5.2.17 with Suhosin-Patch в режиме CLI. Консольное приложение считывает из битрикса через Bitrix API определенный массив юзеров. Далее, в цикле, для каждого юзера идет запрос на получение определенных свойств.

Так вот, для каждого нового юзера время на запрос увеличивается.

Например, для юзера 1 запрос занимал 0.00002 секунды, а для юзера 10000 это уже 0.54323 секунд. Время увеличивается всегда линейно. Память, занимаемая приложением тоже растет.


Пробовали на разных ОС (FreeBSD, последняя Убунта, Винда) — везде одно и тоже. Пробовали ставить и постоянное соединение к базе и НЕ постоянное (в конфиге битрикс). Пробовали даже отключаться от БД каждые 100 итераций и подключатсья заново насильно. Переменные все чистим. Уже замучались.


Вопрос: в чем может быть причина такой деградации? Код вроде уже весь вылизан и проверен несколькими весьма хорошими программистами.


Может ли это быть из-за того, что Битрикс использует стандартный модуль PHP Mysql?


Заранее, спасибо!


upd. Добавил пример кода:

 $subscriber = new Subscribers();

 
$arSubscriberList = $subscriber->getList();

 
$i = 0;

 
while ($i<=count($arSubscriberList)) {

 

 $subscriber = $arSubscriber[$i];

 

 $sql = 'SELECT NAME,LAST_NAME FROM b_user WHERE EMAIL='.subscriber['email'].';';

 $resSubscriber = $DB->Query($sql);

 

 $result[] = $resSubscriber->Fetch();

 

 $i++
}


UPD. Проблема решена.

Кому интересно: решилось всё переписыванием наших классов на singleton.

Додумались мы до этого только после использования профайлера xhprof, а точне XH Gui.
  • Вопрос задан
  • 4564 просмотра
Решения вопроса 1
Stdit
@Stdit
Это замедление распространяется только на один запуск, или на каждый последующий? Я бы для начала поставил профайлер и посмотрел его отчёт по памяти на предмет метода, в котором возникает утечка памяти.
Да, и ещё: почему бы не получить сразу все свойства для всех юзеров одним запросом, а потом сгруппировать и сформировать нужный $result?
Ответ написан
Пригласить эксперта
Ответы на вопрос 8
DrNemo
@DrNemo
я бы попробовал бы для начала реализовать этот же пример на чистом php, хотя бы отправку запроса и посмотреть итоги.
если потери по времени не будет, поздравляю, битрикс.
*но по теме, но код я бы написал так
$subscriber = new Subscribers(); $arSubscriberList = $subscriber->getList(); foreach($arSubscriberLis as $subscriber) { $sql = 'SELECT NAME,LAST_NAME FROM b_user WHERE EMAIL='.subscriber['email'].';'; $resSubscriber = $DB->Query($sql); $result[] = $resSubscriber->Fetch(); }
Ответ написан
Skpd
@Skpd
Попробуйте сделать стриминг, если это возможно.

У Вас, насколько я понял, собираются все данные вместе в $result. Если данных действительно много, то может банально не хватить памяти для кэша, или даже для работы без подкачки.
Ответ написан
script88
@script88
1 Конфиг в студию
2 Пробовали запрос в консоли выполнять?
3 Настроен ли кеш в мускуле?
Ответ написан
dmitryrublev
@dmitryrublev
Веб-разработчик, зануда
Сложно без кода сказать.
Можеть быть, где-то есть зацикливание, или рекурсивные вызовы.
Ответ написан
Как время исполнения запроса измеряете?

$subscriber->getList() — возвращает массив?
Ответ написан
Wott
@Wott
Вы неэффективно используете базу. Каждый раз вы делаете запрос мимо кэша да еще через кучу прокладок. Если для кэша установлено достаточно большое значение то он будет расти, пока не упрется в лимит.

По хорошему запрос должен быть один — «взять всех пользователей вместе с именем».
Хотя мне сложно представить зачем вдруг вам понадобились сразу все пользователи.

Надеюсь с индексами в базе все нормально.
Ответ написан
@Vampiro
Я, конечн, жопорукий извращенец, но почему нельзя сделать таблицу subscribers, заполнить ее один раз всеми значениями при добавлении подписчика, а при рассылке тупо из нее дергать?

И еще, в порядке бреда, проблема может быть в пыхе, на этапе выделения оперативки. Попробуйте для теста 5.4 не меняя остального. Не помню на какой версии у меня была такая проблема.
Ответ написан
Nastradamus
@Nastradamus Автор вопроса
Кому интересно: решилось всё переписыванием наших классов на singleton.
Додумались мы до этого только после использования профайлера xhprof, а точне XH Gui.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы