通过平面文件读取738627条记录会导致内存耗尽错误

时间:2010-07-20 19:34:45

标签: mysql memory memory-leaks php

我正在尝试阅读一个简单的平面文件,其中有738,627条记录,该文件的示例如下所示:

#export_dategenre_idapplication_idis_primary
#primaryKey:genre_idapplication_id
#dbTypes:BIGINTINTEGERINTEGERBOOLEAN
#exportMode:FULL
127667880285760002817317350
127667880285760002818261461
127667880285760002825372301
127667880285760002827785570
127667880285770193778591110
127667880285770193778771240
127667880285770193779116230
127667880285770193779482590
127667880285770193779623800
127667880285770193780516840
#recordsWritten:738627

我的相关PHP代码如下所示

 ini_set("memory_limit","40M"); 
$fp1 = fopen('genre_application','r');
if (!$fp) {echo 'ERROR: Unable to open file.'; exit;}

$loop = 0;
while (!feof($fp1)) {
  $loop++;
    $line = stream_get_line($fp1,128,$eoldelimiter); //use 2048 if very long lines
if ($line[0] === '#') continue;  //Skip lines that start with # 
    $field[$loop] = explode ($delimiter, $line);
list($export_date, $genre_id, $application_id, $is_primary ) = explode($delimiter, $line);

// does application_id exist? 
$application_id = mysql_real_escape_string($application_id); 
$query = "SELECT * FROM jos_mt_links WHERE link_id='$application_id';"; 
$res = mysql_query($query); 
if (mysql_num_rows($res) > 0) { 
 echo $application_id . "application id" . $link_id . "\n";
} else 
{
// no, application_id doesn't exist 
echo $loop . "\n";
}

} //close reading of genre_application file
fclose($fp1);

我屏幕上的最后一个输出如下,所以它甚至没有通过前100,00条记录。有没有办法防止脚本内存不足?

81509
81510
81511
81512
81513
81514
81515
81516
  

PHP致命错误:第156行的/var/www/vhosts/smartphonesoft.com/httpdocs/fred/xmlfeed/test/text_to_mysql.php中允许的内存大小为41943040字节(试图分配14个字节)

     

致命错误:第156行的/var/www/vhosts/smartphonesoft.com/httpdocs/fred/xmlfeed/test/text_to_mysql.php中允许的内存大小为41943040字节(试图分配14个字节)

5 个答案:

答案 0 :(得分:2)

您似乎将每行都存储在您引用的脚本之外初始化的数组中:

 $field[$loop] = explode ($delimiter, $line);

为什么呢?这必然会随着每个循环而增长,直到达到40MB的限制。

我认为如果您将其删除,或将其更改为仅仅$field = ...,它就会有效。

答案 1 :(得分:0)

您正在为从文件读取的每一行填充$ field [$ loop],因此这个数组在循环的每次迭代中都在增长。你真的需要在记忆中成长吗?

答案 2 :(得分:0)

您可以回答自己的问题......您希望将738,627个文本数组存储到内存中。是否有理由将所有爆炸线保留在字段$?

答案 3 :(得分:0)

您可以像这样增加可用内存量:ini_set("memory_limit","64M"); ...只需将它放在PHP文件的顶部即可。如果它仍然没有足够的内存,请将其提升至128或256兆。

但是,在您的具体情况下,您没有有效地使用可用内存...请参阅Pekka的答案。

答案 4 :(得分:0)

你有... ...

$res = mysql_query($query);

你不应该有吗?...

if (isset ($res))
{
    mysqli_free_result ($res);
}

$res = mysql_query($query);
相关问题