如何减少 PHP/MySQL 的内存消耗?
Posted
技术标签:
【中文标题】如何减少 PHP/MySQL 的内存消耗?【英文标题】:How to reduce PHP/MySQL memory consumption? 【发布时间】:2019-03-02 09:55:34 【问题描述】:php 7,mysqli,参考:Example of how to use bind_result vs get_result
我正在使用unbuffered fetching(我希望)并且想知道$m
的内存消耗。当我只是获取(测试用例)时,我希望内存$m
几乎是恒定的。但事实并非如此,这取决于我获取的行数会增加。我希望获取结果的工作方式就像一个游标一次只能获取 1 行。
我将如何实现(一次读取 1 行)?
备注:这里https://***.com/a/14260423/356726他们使用
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
但我还没有找到在准备好的语句中传递MYSQLI_USE_RESULT
的方法。
$result = $stmt->get_result(); // not stored I hope
$i = 0;
while ($row = $result->fetch_assoc())
$i++;
if ($i > 20000)
break;
$m = memory_get_usage(); // see values between 10-50MB here, depending on i
$this->freeAndCloseStatement($stmt);
【问题讨论】:
如果使用bind_result()
和fetch()
而不是get_result()
和fetch_assoc()
,内存消耗如何?
大小差不多,也不是 const,而是随着获取行的大小而增加。当我释放 SQL 资源(关闭)时,我看到内存急剧下降。意味着结果以某种方式消耗了内存,这正是我不应该在无缓冲结果中看到的(至少这是我的理解,为什么它被称为无缓冲)。
那么我很茫然。虽然准备好的语句默认情况下是无缓冲的,但get_result()
返回一个缓冲的结果集。所以我认为使用bind_result()
可以解决问题。
主要问题不是那一行的缓冲,而是所有已经读取的行的缓冲(不需要的行为)。下一个问题是我达到了 128MB 的脚本内存限制,尽管 memory_get_usage
只显示 80MB。都很奇怪。
【参考方案1】:
Mysql Documentation上有一个例子,所以你不要作为参数,只是运行一个方法。
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno())
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
$query = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";
/* execute multi query */
if ($mysqli->multi_query($query))
do
/* store first result set */
if ($result = $mysqli->use_result()) //<----------- THIS LINE
while ($row = $result->fetch_row())
printf("%s\n", $row[0]);
$result->close();
/* print divider */
if ($mysqli->more_results())
printf("-----------------\n");
while ($mysqli->next_result());
/* close connection */
$mysqli->close();
?>
https://dev.mysql.com/doc/apis-php/en/apis-php-mysqli.use-result.html
对于准备好的语句,您可以将属性设置为 false。
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
【讨论】:
我在while
之前、get_result()
之前和查询之前在 3 个地方尝试了 $this->_connection->use_result();
。内存消耗没有变化,在所有 3 个场景中的值相同。以上是关于如何减少 PHP/MySQL 的内存消耗?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Node.js Stream API 减少服务器端内存消耗?
如何使用 Node.js Stream API 减少服务器端内存消耗?