PHP7的PDO扩展是否会将整个结果集读入内存?

13

我注意到自从我升级到PHP7后,一些SQL语句不再起作用,而是会耗尽内存。

我有以下代码:

$query = Yii::$app->db->createCommand('select * from tbl_title')->query();
while ($row = $reader->read()) {
    var_dump($row);
    exit();
}

而 Yii2 的数据库抽象只是 PDO 上的一个非常薄的层,并没有做任何额外的事情。query() 除了为了分析记录并添加一行到一个日志文件(Yii2 的)之外,没有做任何额外的工作。而 reader->read() 只是调用了 PDO 流的 fetch() 函数。

但当我尝试报告我的表的大小时,即尝试分配385 MB的进程内存时,它会耗尽内存:

  

已用尽 134217728 字节的内存限制(尝试分配 385883840 字节)

如果使用结果集完全适合 PHP 进程128 MB限制的查询,则可以解决这个问题。

那么,PHP7 是否发生了改变,我能否将其改回去?

1个回答

11

这与PHP7无关,问题出在新的mysqlnd驱动程序上,因此即使在PHP 5.x上也可能遇到相同的问题。实际上这是一个bug修复,因为即使以前仍然分配了内存,但它不计入memory_limit

为避免内存问题,您需要对大型结果集使用非缓冲查询

因此,对于预期有大量数据集的查询,请设置正确的设置,如下所示:

$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

如果您想进一步阅读,我在我的PDO教程中有一个不错的解释,感谢Nikic提供的宝贵批评意见。


3
请记住副作用,例如无法运行嵌套查询和获取行数。 - Your Common Sense
嗯,它也会阻止所有未缓冲的其他查询。 - Sammaye
@rustyx 真遗憾。谢谢,已修复。 - Your Common Sense

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接