[英]Memory leak in PHP when fetching large dataset from MySQL
When I execute the following code for a user table of about 60,000 records: 当我为大约60,000条记录的用户表执行以下代码时:
mysql_connect("localhost", "root", "");
mysql_select_db("test");
$result = mysql_query("select * from users");
while ($row = mysql_fetch_object($result)) {
echo(convert(memory_get_usage(true))."\n");
}
function convert($size) {
$unit=array('b','kb','mb','gb','tb','pb');
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
I get the following error: 我收到以下错误:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes)
Any thoughts on how to avoid having the script take up additional memory with each pass through the loop? 是否有关于如何避免脚本在每次循环中占用额外内存的想法? In my actual code I'm trying to provide a CSV download for a large dataset, with a little PHP pre-processing.
在我的实际代码中,我试图为大型数据集提供CSV下载,并进行一些PHP预处理。
Please don't recommend increasing PHP's memory limit--it's a bad idea and, more importantly, will still create an upward bound on how large a dataset can be processed with this technique. 请不要建议增加PHP的内存限制-这是一个坏主意,更重要的是,仍然会限制使用此技术可以处理多大数据集。
I'm not 100% sure if this will solve your problem, but have you considered using PDO ? 我不确定100%是否可以解决您的问题,但是您是否考虑过使用PDO ? It has several advantages;
它具有几个优点; you can read more about them here .
您可以在此处阅读有关它们的更多信息。 If you do go in that direction, there is a similar question about memory usage here .
如果你往那个方向,有关于内存使用一个类似的问题在这里 。
mysql_query buffers the entire result set into php memory. mysql_query将整个结果集缓冲到php内存中。 This is convenient and generally very fast, but you're experiencing a drawback to it.
这很方便并且通常非常快,但是您遇到了一个缺点。
mysql_unbuffered_query () exists. mysql_unbuffered_query ()存在。 It doesn't grab the entire result set all at once.
它不会一次获取全部结果集。 It grabs little pieces at a time when you fetch rows from the result set.
当您从结果集中获取行时,它一次抓取一些小片段。
I have had a similar problem. 我有类似的问题。 What I did to get it to work was to create a temporary file (you can use hash or something similar to keep a record of the name).
我要做的就是创建一个临时文件(您可以使用哈希或类似的方法来保存名称记录)。
Go like that in circles until you got it all. 像这样绕圈走,直到掌握全部。 I had to do this work around for two reasons,
我不得不做此工作有两个原因,
Drawbacks of this method is that it requires many HTTP calls to get data. 该方法的缺点是它需要许多HTTP调用才能获取数据。 Also in the mean time there could be rows that have changed etc. It is a pretty "dirty" way of doing it.
同时,也可能有行已更改等。这是一种非常“肮脏”的方式。 I'm yet to find something that works better.
我还没有找到更好的方法。 Hope that helps.
希望能有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.