php - 使用单个 PDO 查询意外达到 PHP 内存限制?

标签 php mysql memory pdo

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

$result = $pdo->query('SELECT * FROM my_table');

foreach($result as $r) {
    // do some stuff
}

但是当我运行它时,我收到以下错误:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /path/to/myfile.php on line 15

“第 15 行”是 $pdo->query 行。

如果我把 die() 放在查询之后,我仍然会得到同样的错误。

我认为这应该一次只获取一行;为什么会占用这么多内存?

最佳答案

Memory usage is 635384 bytes before calling query. I'm guessing query allocates in chunks, for each record.

叮叮叮!

连接 MySQL 时,PHP 喜欢使用 buffered queries .无论您使用什么方法进行连接,这都是正确的。使用缓冲查询时,会立即获取整个结果集,而不是在您询问时获取。这通常对性能有好处,因为往返次数较少。

但就像 PHP 中的所有内容一样,有一个陷阱。如缓冲页面所述:

When using libmysql as library PHP's memory limit won't count the memory used for result sets unless the data is fetched into PHP variables. With mysqlnd the memory accounted for will include the full result set.

您使用的是 PHP 5.3,这意味着您很有可能使用的是 mysqlnd。

您需要在此处关闭缓冲查询。它在 MySQL 的每个 PHP 接口(interface)中都以不同的方式完成:

  • 对于 PDO,您需要将 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 属性设置为 false
  • 对于 mysqli,您需要将 MYSQLI_USE_RESULT 常量传递给 query方法。
  • 对于 mysql,你需要调用 mysql_unbuffered_query 而不是 mysql_query

页面上有完整的详细信息和示例。

大胖无缓冲查询陷阱!

必须在发出另一个查询之前正确关闭语句句柄并释放结果集:

  • 在 PDO 中,这意味着调用 closeCursor在语句句柄上。
  • 在 mysqli 中,这意味着调用 free_result在语句句柄上或 free在结果句柄上,具体取决于您正在使用的内容。
  • 在mysql中,这意味着调用mysql_free_result

不这样做会导致错误。

关于php - 使用单个 PDO 查询意外达到 PHP 内存限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13728106/

相关文章:

php - Capifony部署到服务器X,清除服务器X和Y上的APC缓存

mysql - Apache 的 htdocs 文件夹发生了什么变化?

Python:在 numpy 中定义矩阵的内存优化方式

algorithm - 为什么 Merge 排序空间复杂度为 O(n)?

php - 是什么导致 PHP 中出现 "Unable to allocate memory for pool"?

php - 图像旋转中的背景透明度()

php - 如何将斜杠后面的所有内容重定向到之前的域?

PHP:在 For 循环中创建唯一变量

php - jQuery Combobox 和数据库问题

mysql - 连接 MySQL 时出错 : Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (13)