在PHP中,当我们使用mysql\u查询时,内存中会发生什么
我曾经使用mysql_查询获取大量数据,然后逐一迭代结果以处理数据。例:在PHP中,当我们使用mysql\u查询时,内存中会发生什么,php,mysql,memory,pointers,heap,Php,Mysql,Memory,Pointers,Heap,我曾经使用mysql_查询获取大量数据,然后逐一迭代结果以处理数据。例: $mysql_result = mysql_query("select * from user"); while($row = mysql_fetch_array($mysql_result)){ echo $row['email'] . "\n"; } 最近,我查看了一些框架,发现它们将所有数据提取到内存中的一个数组中,并返回该数组 $large_array = $db->fetchAll("select
$mysql_result = mysql_query("select * from user");
while($row = mysql_fetch_array($mysql_result)){
echo $row['email'] . "\n";
}
最近,我查看了一些框架,发现它们将所有数据提取到内存中的一个数组中,并返回该数组
$large_array = $db->fetchAll("select * from user");
foreach($large_array as $user){
echo $user['email'] . "\n";
}
我想知道每种方法的优缺点。在我看来,如果你有一个很长的项目列表,那么在内存中加载所有东西都会导致灾难。但是,一位同事再次告诉我,无论如何mysql驱动程序都必须将结果集放在内存中。我想征求一些人的意见,他们明白问题在于绩效。请不要对代码发表评论,我只是为这篇文章编了一个例子
感谢我在性能方面学到了一些东西:
foreach
比while
循环快。也许您应该对每个测试的结果进行基准测试,看看哪一个更快、内存占用更少。嗯,我更喜欢后一种方法。但是您真的需要用户表中的每一列吗?如果没有,则只定义所需的列,而不是使用*
获取所有列。因为这也有助于提高内存和速度。你把事情搞混了
- 可用性,这使您的代码在使用数组时更加流畅
- 和未优化的算法,当没有经验的程序员倾向于将所有数据加载到脚本中,而不是让数据库来完成所有计算或获取部分数据时
所以,一个好的程序员不会将大量数据提取到数组中。在这几个真正需要的情况下,可以使用旧的逐行获取(每个框架都为此提供了一种方法)。在所有其他情况下,应使用数组中已存在的平滑回迁 还请注意,框架永远不会做像在数据库循环内部回显数据这样的事情。
每一个好的框架都会使用一个模板来输出内容,在这种情况下,数组非常方便。在处理大型结果集时,我通常会分批处理,如下所示:
$current = 0;
$batchSize = 1000;
while (true) {
$large_array = $db->fetchAll(sprintf("select * from user limit %s, %s", $current, $batchSize));
if (sizeof($large_array) == 0) {
break;
}
$current += sizeof($large_array);
foreach($large_array as $user){
echo $user['email'] . "\n";
}
}
只要代码不泄漏内存,就不必担心哪种方法会占用更多内存。就性能而言,在一个查询中加载整个结果集可能更快,尽管这样很快就会达到内存限制,因此性能不再是您真正的问题
顺便说一句,通过设置一个脚本来测量两个代码段的时间(和峰值内存),您自己测试这一点相对容易。我敢打赌,它们在时间上不会有太大差异。的确,MySQL库“正常”获取客户端内存中的所有数据。它通常通过使用。您可以使用
LIMIT
关键字拆分如上所示的过大查询,但存在数据不一致的风险,因为它们可能在这两个关键字之间发生变化。你可以使用锁来处理这个问题
另一种方法是使用,它在服务器端使用更多的资源,并且需要尽快完成抓取作业。相比之下,请查看。OMG foreach比whileyes更快。在处理大型数据数组时,尽可能使用
foreach
,而不是while
循环。这已经被一次又一次地证明了…问题不在于foreach vs while。这种比较是没有用的:你执行一个12秒的sql查询,但是你试图优化0.1秒的循环…是的,假设你是对的,只是想帮助你。事实上,这个问题是关于while+foreach和while的。不管怎么说,雷米是对的,这样的差异无论如何都不重要为什么不做一个while循环呢?是的,我可以测试自己,但我很懒。我更好奇的是专业人士对它的看法。例如,这里的一些人提出了不同的方法并加以解释。对我来说,这比测试要好。我很生气o) 对不起,斯汀姆特。我现在把它改了,这样你们大家都能从中受益:-)谢谢,榴弹上校。回复:这只是一个例子来说明。