После выполнения этого простого кода (для базы данных MySQL) я получаю меньше 1 Кбайт памяти для каждой итерации цикла, поэтому после 1000-й итерации у меня есть около 1 МБ памяти.
Теперь, если мне нужно зациклиться на длинном сценарии (около 1 000 000 итераций), я скоро буду не в памяти
$_db = Zend_Db_Table::getDefaultAdapter(); $start_memory = memory_get_usage(); for ($i=0; $i<1000; $i++) { $update_query = "UPDATE table SET field='value'"; $_db->query($update_query); } echo 'memory used: '.(memory_get_usage()-$start_memory);
Есть ли способ освободить память, используемую запросом базы данных?
Я попытался поместить запрос обновления в функцию, поэтому после того, как вы оставите функциональные возможности, ресурсы, используемые этой функцией, должны быть автоматизированы:
function update($_db) { $sql = "UPDATE table SET field='value'"; $_db->query($sql); } ... for ($i=0; $i<1000; $i++) { update($_db); }
но это не так!
Меня не интересуют такие советы, как «попробуйте обновить несколько строк за один раз»;)
Скорее всего, у вас включен Zend_Db_Profiler .
Профайлер базы данных хранит каждый выполненный запрос, который очень полезен для отладки и оптимизации, но приводит к довольно быстрому исчерпанию памяти, если вы выполняете огромное количество запросов.
В примере, который вы указали, отключение профилировщика должно выполнить трюк:
$_db = Zend_Db_Table::getDefaultAdapter(); $_db->getProfiler()->setEnabled(false); $start_memory = memory_get_usage(); for ($i=0; $i<1000; $i++) { $update_query = "UPDATE table SET field='value'"; $_db->query($update_query); } echo 'memory used: '.(memory_get_usage()-$start_memory);
При выполнении одного и того же запроса несколько раз лучший способ сохранить память – реализовать подготовленные операторы . Ваш адаптер будет использовать подготовленные операторы, но поскольку вы вызываете метод query () внутри цикла, он становится готовым каждый раз. Переместите это за пределы цикла:
$_db = Zend_Db_Table::getDefaultAdapter(); $_stm = $_db->prepare("UPDATE table SET field='?'"); for ($i=0; $i<1000; $i++) { $_stm->execute(array($fieldValue)); }