我有一个非常简单的查询,如下所示:
$result = $pdo->query('SELECT * FROM my_table');
foreach($result as $r) {
// do some stuff
}
但是当我运行这个时,我收到以下错误:
致命错误:第 15 行 /path/to/myfile.php 中允许的内存大小 134217728 字节已耗尽(尝试分配 32 字节)
“15号线”是$pdo->query
line.
如果我把die()
查询后,我仍然收到相同的错误。
我认为这一次只能获取一行;为什么它使用这么多内存?
调用查询之前,内存使用量为 635384 字节。我猜测查询会为每条记录分块分配。
叮叮叮!
当连接MySQL时,PHP喜欢使用缓冲查询 http://php.net/mysqlinfo.concepts.buffering。无论您使用什么方法进行连接,都是如此。使用缓冲查询时,会立即获取整个结果集,而不是在您询问时才获取。这是usually有利于性能,因为往返次数较少。
但就像 PHP 中的一切一样,也有一个陷阱。正如缓冲页面上所述:
当使用 libmysql 作为库时,PHP 的内存限制不会计算用于结果集的内存,除非数据被提取到 PHP 变量中。对于 mysqlnd,占用的内存将包括完整的结果集。
您正在使用 PHP 5.3,这意味着您很有可能正在使用 mysqlnd。
您需要在此处关闭缓冲查询。每个 PHP 到 MySQL 的接口都有不同的做法:
- 对于 PDO,您需要设置
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
归因于false
.
- 对于 mysqli,您需要传递
MYSQLI_USE_RESULT
常数为query http://php.net/mysqli.query method.
- 对于mysql,你需要调用
mysql_unbuffered_query
代替mysql_query
.
完整的详细信息和示例位于页面上。
巨大的无缓冲查询陷阱!
You must在发出另一个查询之前正确关闭语句句柄并释放结果集:
- 在 PDO 中,这意味着调用closeCursor http://php.net/pdostatement.closecursor在语句句柄上。
- 在 mysqli 中,这意味着调用free_result http://php.net/mysqli-stmt.free-result在语句句柄上或free http://php.net/mysqli-result.free在结果句柄上,具体取决于您正在处理的内容。
- 在mysql中,这意味着调用mysql_free_result http://php.net/function.mysql-free-result
如果不这样做将会导致错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)