繁体   English   中英

PHP + MySQL:缓冲和非缓冲查询之间的区别

[英]PHP + MySQL: Difference between buffered and unbuffered queries

我一直认为,简单来说,PHP/MySQL 缓冲查询和无缓冲查询之间的区别在于缓冲(默认)将所有数据加载到结果集变量中,然后您可以开始使用它们,而无缓冲在一个时间。

假设你运行了SELECT * FROM sometable然后做了$result = $db->query($query); , $result将包含所有行和补充信息,例如行数。 因此,如果您在 100MB 的数据库上执行此操作,如果那里没有索引,您会期望$result占用约 100MB)。

但是,我遇到了这个SO 溢出问题,其中部分说明了缓冲查询:

[The] 结果将包含一些依赖于实现的行缓冲区。 它可能是 100 行或更多或更少。 每行返回所有列; 随着您最终获取更多行,客户端将要求服务器提供更多行。 这可能是在客户端用完时,也可能是抢先完成。

这是对的,真的还有一些缓冲吗? 如果是这样,我们一般不用担心 PHP 在处理大型结果集时会耗尽内存吗? 这很奇怪,因为我一直在 40MB 的测试表上运行一些测试缓冲查询,而 PHP 总是报告 ~5MB 的峰值内存使用量。

最后,根据经验,什么时候选择无缓冲而不是缓冲? 你能提供一个例子吗?

谢谢。

(顺便说一下,我正在使用 MySQLi。我假设主体是相同的)。

编辑:我现在读了更多,甚至更加困惑。 http://php.net/manual/en/mysqli.quickstart.statements.php 上它说

On After 语句的执行结果可以一次检索到由客户端缓存或逐行读取。 客户端结果集缓冲允许服务器尽早释放与语句结果相关的资源。 一般来说,客户端消耗结果集的速度很慢。 因此,建议使用缓冲结果集。 mysqli_query() 结合了语句执行和结果集缓冲。

PHP 应用程序可以在缓冲结果中自由导航。 导航速度很快,因为结果集保存在客户端内存中。 请记住,通过客户端扩展通常比扩展服务器更容易。

http://php.net/manual/en/mysqli-result.fetch-all.php 上它说:

由于 mysqli_fetch_all() 在单个步骤中将所有行作为数组返回,因此它可能比某些类似函数(例如 mysqli_fetch_array() 一次仅从结果集中返回一行)消耗更多内存。 此外,如果您需要迭代结果集,您将需要一个循环结构,这将进一步影响性能。 出于这些原因,mysqli_fetch_all() 应该只在获取的结果集将被发送到另一层进行处理的情况下使用。

这似乎有些矛盾。 “客户端结果集缓冲”和“消费结果集”有什么区别? 一个说它们保存在客户端内存中,另一个说逐行读取。 如果整个事情都缓冲到 PHP 为什么最后一个引号说如果您在单个步骤中将所有行作为数组返回,它可能会消耗更多内存?

见: http : //php.net/manual/en/mysqlinfo.concepts.buffering.php

无缓冲的 MySQL 查询执行查询,然后在数据仍在 MySQL 服务器上等待获取时返回资源。 这在 PHP 端使用较少的内存,但会增加服务器的负载。 除非从服务器获取完整的结果集,否则无法通过同一连接发送进一步的查询。 无缓冲查询也可以称为“使用结果”。

如果您只期望有限的结果集或需要在读取所有行之前知道返回的行数,则应遵循这些特征使用缓冲查询。 当您希望获得更大的结果时,应使用无缓冲模式。

缓冲查询是默认的。

无缓冲示例:

<?php
$mysqli  = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);

if ($uresult) {
   while ($row = $uresult->fetch_assoc()) {
       echo $row['Name'] . PHP_EOL;
   }
}
$uresult->close();
?>

希望这可以帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM