用一个PDO查询意外地达到PHP内存限制?

用一个PDO查询意外地达到PHP内存限制?,php,mysql,memory,pdo,Php,Mysql,Memory,Pdo,我有一个非常简单的查询,看起来像: $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(),仍然会得到相同的错误 我以为

我有一个非常简单的查询,看起来像:

$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()
,仍然会得到相同的错误

我以为这一次只能拍到一排;为什么它会占用这么多内存

在调用查询之前,内存使用量为635384字节。我猜查询会为每个记录分块进行分配

叮叮

当连接到MySQL时,PHP喜欢使用。无论您使用什么方法连接,这都是正确的。使用缓冲查询时,将立即获取整个结果集,而不是在您请求时获取。这通常有利于性能,因为往返次数较少

但是就像PHP中的所有东西一样,有一个问题。如缓冲页上所述:

当使用libmysql作为库时,PHP的内存限制不会计算用于结果集的内存,除非数据被提取到PHP变量中。对于mysqlnd,占用的内存将包括完整的结果集

您正在使用PHP5.3,这意味着您很有可能正在使用mysqlnd

您需要在此处关闭缓冲查询。MySQL的每个PHP接口都有不同的做法:

  • 对于PDO,您需要将
    PDO::MYSQL\u ATTR\u USE\u BUFFERED\u QUERY
    属性设置为
    false
  • 对于mysqli,需要将
    mysqli\u USE\u RESULT
    常量传递给该方法
  • 对于mysql,您需要调用
    mysql\u unbuffered\u query
    ,而不是
    mysql\u query
完整的细节和例子在页面上

大胖子无缓冲查询明白了! 在发出另一个查询之前,必须正确关闭语句句柄并释放结果集:

  • 在PDO中,这意味着调用语句句柄
  • 在mysqli中,这意味着调用语句句柄或结果句柄,这取决于您使用的是什么
  • 在mysql中,这意味着调用

否则将导致错误。

@WesleyMurch:Hrm?这有什么关系?我只使用
$r
这是一条记录。为什么这会导致它获取额外的数据。。。除非内存泄漏,并且额外的迭代是导致问题的原因…好的,我会发布它。为什么要否决?获取实际的内存限制错误也会很有帮助(实际使用的措辞,请参见),因此在查询之前也会很有帮助。在查询之前,您可能已经达到限制。另外,查询返回了多少条记录?您正在执行一个
选择*
,没有
限制
。返回一百万行只需要一点内存。伙计,它分配了32个字节,而你达到了128M的限制?在查询之前,您确实需要检查内存使用情况。还有,这是什么PHP版本?@Charles:在调用
query
之前,内存使用量是635384字节。我猜
query
为每条记录分块分配。这证明不了什么。它是PHP5.3.17.MySQL,对吗?您正在使用PDO::MYSQL\u ATTR\u USE\u BUFFERED\u QUERY?是的。如果使用
fetchAll
或迭代整个结果集,我认为不需要调用
closeCursor
;仅当您还有未蚀刻的行时。无论如何,回答得很好!再次感谢。老实说,我从来没有尝试过,因为将unbuffered和fetchAll组合起来听起来非常愚蠢。确实如此,除非有少数情况下您需要完整的结果集,并且您不想打开或关闭设置。我在这里登录也是因为同样的错误,但是我的问题是没有字段名。导致它达到内存限制。最后没有更多内存\u限制=x GB