我正在编写批处理脚本并收到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行左右,所以这必须是循环中的东西?我希望尽可能避免实施分页。
答案 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}}语法:
答案 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.