我正在编写一个批处理脚本,并得到一个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万行)。
更新:内存不足发生在第400000行附近,所以这一定是循环中的事情吗?如果可能的话,我希望避免必须实现分页
尝试使用http://www.php.net/manual/en/function.mysql-unbuffered-query.php(mysql_unbuffered_query()),以防止将整个表加载到内存中,但仍避免分页。
将查询限制为1k个结果,然后再次执行(当然要使用偏移量),直到您浏览完所有表。您当前的未设置并没有什么区别,因为每次while迭代都会覆盖$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
如果您使用MySQL,请对结果进行分页,以免耗尽可用内存。MySQL本身占用了数据库结果集的内存。查看以下链接,特别是SELECT
:的LIMIT offset, limit
语法
http://dev.mysql.com/doc/refman/5.0/en/select.html
我在使用大型数据库时遇到了同样的问题。尽管在大约400000条记录中取消了$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.