在执行这个简单的代码(对于MySQL数据库)之后,每次循环迭代我得到的内存少1kB,所以在第1000次迭代后我使用了大约1MB的内存。
现在,如果我必须循环一个长时间运行的脚本(大约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);
}
但他们不是!
我对像'尝试一次更新多行'这样的建议不感兴趣;)
答案 0 :(得分:6)
很可能您已启用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);
答案 1 :(得分:0)
多次执行同一查询时,保存内存的最佳方法是实现prepared statements。你的适配器将使用预准备语句,但由于你在循环中调用query()方法,它每次都准备好了。将其移到循环外部:
$_db = Zend_Db_Table::getDefaultAdapter();
$_stm = $_db->prepare("UPDATE table SET field='?'");
for ($i=0; $i<1000; $i++) {
$_stm->execute(array($fieldValue));
}