我有一个非常简单的查询,看起来像:
$result = $pdo->query('SELECT * FROM my_table');
foreach($result as $r) {
// do some stuff
}
但是当我运行这个时,我收到以下错误:
致命错误:第15行的/path/to/myfile.php中允许的内存大小为134217728个字节(尝试分配32个字节)
“第15行”是$pdo->query
行。
如果我在查询后放die()
,我仍然会收到相同的错误。
我以为这只能在一次获取一行;它为什么要使用这么多内存?
答案 0 :(得分:28)
丁丁丁!调用查询之前,内存使用量为635384字节。我猜测查询是按块分配给每条记录的。
连接到MySQL时,PHP喜欢使用buffered queries。无论您使用何种方法进行连接,都是如此。使用缓冲查询时,会立即获取整个结果集,而不是在您询问时获取。这通常通常对性能有好处,因为往返次数较少。
但是像PHP中的所有东西一样,有一个问题。如缓冲页面所述:
当使用libmysql作为库时,PHP的内存限制将不计算用于结果集的内存,除非将数据提取到PHP变量中。使用mysqlnd时,占用的内存将包括完整的结果集。
你正在使用PHP 5.3,这意味着你很有可能使用mysqlnd。
您需要在此处关闭缓冲查询。在MySQL的每个PHP接口中都有不同的做法:
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
属性设置为false
。MYSQLI_USE_RESULT
常量传递给query
方法。mysql_unbuffered_query
而不是mysql_query
。页面上有完整的详细信息和示例。
您必须正确关闭语句句柄并释放结果集,然后再发出另一个查询:
closeCursor
。free_result
或在结果句柄上调用free
,具体取决于您正在使用的内容。 mysql_free_result
如果不这样做,将导致错误。