为什么“允许的内存大小耗尽”?

时间:2012-02-11 18:55:33

标签: php memory

我正在编写批处理脚本并收到Allowed memory size of 134217728 bytes exhausted错误。

我不明白为什么记忆力正在填满。我尝试取消设置$row变量,但这没有改变。这是我的代码:

// ... (sql connection)
$result = mysql_query("SELECT * FROM large_table");

while ($row = mysql_fetch_array($result)) {
    echo $row['id'] . PHP_EOL;
    unset($row);
}

(简化代码)

为什么内存会填满,我该如何避免?

注意:这是一个批处理脚本。这是正常的,我必须处理这样的数据(通过100万行)。

更新:内存不足发生在第400 000行左右,所以这必须是循环中的东西?我希望尽可能避免实施分页。

4 个答案:

答案 0 :(得分:12)

尝试使用http://www.php.net/manual/en/function.mysql-unbuffered-query.php(mysql_unbuffered_query())来阻止整个表加载到内存中,但仍然避免分页。

答案 1 :(得分:4)

将您的查询限制为例如1k结果并再次执行(使用偏移量),直到您完成所有表格。 你当前的unset没有任何区别,因为$ row会在每次迭代时被覆盖,所以你可以跳过它。

$chunk_size = 1000;
$done = 0;

$keep_asking_for_data = true;
do{
    $result = mysql_query("SELECT * FROM `large_table` LIMIT {$done}, {$chunk_size}");
    $num_rows = mysql_num_rows($result);
    if($num_rows){
        $done += $num_rows;
        while($row = mysql_fetch_assoc($result)){
            echo "{$row['id']}\n";
        }
    } else {
        $keep_asking_for_data = false;
    }
    mysql_free_result($result);
}while($keep_asking_for_data);

刚刚编译好我的头,希望它有效= D

答案 2 :(得分:1)

如果您使用的是MySQL,请将结果分页,以免耗尽可用内存。 MySQL本身正在使用您的数据库结果集占用这个内存。请查看以下链接,尤其是LIMIT offset, limit的{​​{1}}语法:

http://dev.mysql.com/doc/refman/5.0/en/select.html

答案 3 :(得分:1)

我遇到了与大型数据库相同的问题。尽管在大约400,000条记录中取消了$ row变量,但内存不足,但是无缓冲的查询修复了它。

仅供其他人参考(当我再次这样做时,我也会参考!),一些无缓冲的查询示例代码是:

$sql = "SELECT SEQ, RECTYPE, ROSTERGRP, EMPNM, EMPNUM, DT, RDUTYCAT, ADUTYCAT FROM " .
        $tblRosters . " ORDER BY EMPNUM,DT";
$result  = mysql_unbuffered_query( $sql, $dbConn );
$svRow = array();
while ( $row = mysql_fetch_array( $result ) )
    {
         // your processing code here
    }
    // Unset, close db etc. if you are finished goes here.