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

PHP+MySQL:缓冲查询和非缓冲查询之间的区别,php,mysql,Php,Mysql,我总是觉得PHP/MySQL缓冲查询和非缓冲查询之间的区别很简单,缓冲默认值将所有数据加载到结果集变量中,然后您可以开始使用它们,而非缓冲每次加载一行 假设您从某个表中运行SELECT*,然后执行$result=$db->query$query$结果将包含所有行和补充信息,如行数。因此,如果在100MB数据库上执行此操作,如果没有索引,则$result将占用~100MB的空间 但是,我遇到了这一部分,其中提到了缓冲查询: [结果]将包含一些依赖于实现的行缓冲区。它可能是100行或更多或更少。返回

我总是觉得PHP/MySQL缓冲查询和非缓冲查询之间的区别很简单,缓冲默认值将所有数据加载到结果集变量中,然后您可以开始使用它们,而非缓冲每次加载一行

假设您从某个表中运行SELECT*,然后执行$result=$db->query$query$结果将包含所有行和补充信息,如行数。因此,如果在100MB数据库上执行此操作,如果没有索引,则$result将占用~100MB的空间

但是,我遇到了这一部分,其中提到了缓冲查询:

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

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

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

谢谢

顺便说一下,我正在使用MySQLi。我假设校长是一样的

编辑:我现在读得更多了,甚至更困惑了。上面写着

On After语句执行结果可以一次检索,由客户机缓冲或逐行读取。客户端结果集缓冲允许服务器尽早释放与语句结果关联的资源。一般来说,客户端是缓慢消耗的结果集。因此,建议使用缓冲结果集。mysqli_查询结合了语句执行和结果集缓冲

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

上面写着:

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

这似乎有些矛盾。“客户端结果集缓冲”和“使用结果集”之间有什么区别?一个表示它们保存在客户机内存中,另一个表示逐行读取。如果整个过程都缓冲到PHP中,那么为什么最后一句话说如果在一个步骤中以数组形式返回所有行,可能会消耗更多内存?

请参阅:

无缓冲MySQL查询执行查询,然后返回资源 而数据仍在MySQL服务器上等待获取。 这会在PHP端使用更少的内存,但会增加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();
?>

希望这有帮助

缓冲是在sql server内部处理的,而不是与上面的编辑相关的PHPDO?如果你能在回答中向我解释一下,我会接受的。谢谢。它不应该被称为缓冲tbh,它应该被称为结果缓存。php将保存整个结果对象的一小部分,然后从mysql中提取其余部分。我想不出有人用php做客户端的例子,除非这意味着php是mysql的客户端。Mysql也进行内部查询缓冲和缓存,以加快查找速度,而不必执行完整的表读取等操作。基本上,尽管在Mysql的标准使用中,您不需要担心它,只需让它自己进行排序即可。这里有一个很好的资源:优点。实际上,通过使用free_result释放result资源,您可以在同一个连接上使用多个准备好的语句/查询。但是,这将阻止您从此结果集中获取其他元组/行。