【问题标题】:Does PHP7's PDO ext read the entire result set into memory?PHP7 的 PDO ext 是否将整个结果集读入内存?
【发布时间】:2017-02-08 17:08:11
【问题描述】:

自从我升级到 PHP7 后,我注意到一些 SQL 语句不再有效,而是内存不足。

我有这个代码:

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

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

但是引用我的表的大小(已用空间),它的内存不足,即尝试分配 385 MB 的进程内存:

允许内存大小134217728字节用尽(尝试分配385883840字节)

作为一个扳手,如果我使用其结果集完全符合 PHP 进程的 128 MB 限制的查询。

那么,PHP7 变了,我可以改回来吗?

【问题讨论】:

    标签: php mysql pdo yii2 php-7


    【解决方案1】:

    它与 PHP7 没有直接关系。该问题是由于新的 mysqlnd 驱动程序造成的,因此即使使用 PHP 5.x,您也会遇到同样的问题。这实际上是一个错误修复,因为甚至在内存仍然分配之前,但它并没有计入 memory_limit

    为避免内存问题,您必须对大型结果集使用无缓冲查询

    因此,对于需要大型数据集的查询,请像这样设置正确的设置:

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

    为了进一步阅读,我有一个 decent explanation in my PDO tutorial,感谢 Nikic,他的重要反馈非常宝贵。

    【讨论】:

    • 请记住副作用,例如无法运行嵌套查询和获取行数。
    • 嗯,它还会阻止所有其他未缓冲的查询
    • @rustyx 真可惜。谢谢,已修复
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多