【问题标题】:how to cleanup / free database query memory in zend?如何在 zend 中清理/释放数据库查询内存?
【发布时间】:2012-06-01 11:38:46
【问题描述】:

在执行这个简单的代码后(对于 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);
}

但他们不是!

我对“尝试一次性更新多行”之类的建议不感兴趣;)

【问题讨论】:

    标签: php database zend-framework memory-management


    【解决方案1】:

    很可能您启用了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);
    

    【讨论】:

    • 他们绝对应该在 Zend 网站和所有手册和文档上用大红字写下这一点;)
    • 是的,我之前也遇到过同样的问题(一个 cron 作业突然开始神秘地崩溃,因为它遇到了内存限制)。我花了很长时间才找到导致该问题的分析功能。很高兴我的回答对您有所帮助。
    【解决方案2】:

    多次执行同一查询时,节省内存的最佳方法是实现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));
    } 
    

    【讨论】:

    • 准备一份声明没有帮助
    猜你喜欢
    • 2011-01-23
    • 1970-01-01
    • 2012-06-17
    • 2021-10-14
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    相关资源
    最近更新 更多