此代码需要循环超过350万行,如何才能使其更高效?

Hai*_*ood 6 php mysql optimization

我有一个csv文件,里面有350万个代码.
我应该指出,这只会是这一次.

csv看起来像

age9tlg,  
rigfh34,  
...
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

ini_set('max_execution_time', 600);
ini_set("memory_limit", "512M");
$file_handle = fopen("Weekly.csv", "r");
while (!feof($file_handle)) {
    $line_of_text = fgetcsv($file_handle);

    if (is_array($line_of_text))
        foreach ($line_of_text as $col) {
            if (!empty($col)) {
                mysql_query("insert into `action_6_weekly` Values('$col', '')") or die(mysql_error());
            }
    } else {
        if (!empty($line_of_text)) {
            mysql_query("insert into `action_6_weekly` Values('$line_of_text', '')") or die(mysql_error());
        }
    }
}
fclose($file_handle);
Run Code Online (Sandbox Code Playgroud)

这段代码是否会在我身上消失?我的记忆和最大执行时间是否足够高?

注意:此代码将在我的localhost上运行,并且数据库位于同一台PC上,因此延迟不是问题.


更新:
这是另一种可能的实现.这个是在2000个记录的批量插入中做到的

$file_handle = fopen("Weekly.csv", "r");
$i = 0;
$vals = array();
while (!feof($file_handle)) {
    $line_of_text = fgetcsv($file_handle);

    if (is_array($line_of_text))
        foreach ($line_of_text as $col) {
            if (!empty($col)) {
                if ($i < 2000) {
                    $vals[] = "('$col', '')";
                    $i++;
                } else {
                    $vals = implode(', ', $vals);
                    mysql_query("insert into `action_6_weekly` Values $vals") or die(mysql_error());
                    $vals = array();
                    $i = 0;
                }
            }
        } else {
        if (!empty($line_of_text)) {
            if ($i < 2000) {
                $vals[] = "('$line_of_text', '')";
                $i++;
            } else {
                $vals = implode(', ', $vals);
                mysql_query("insert into `action_6_weekly` Values $vals") or die(mysql_error());
                $vals = array();
                $i = 0;
            }
        }
    }
}
fclose($file_handle);
Run Code Online (Sandbox Code Playgroud)

如果我要使用这种方法,我可以设置它立即插入的最高值是什么?


更新2
所以,我发现我可以使用

LOAD DATA LOCAL INFILE  'C:\\xampp\\htdocs\\weekly.csv' INTO TABLE  `action_6_weekly` FIELDS TERMINATED BY  ';' ENCLOSED BY  '"' ESCAPED BY  '\\' LINES TERMINATED BY  ','(`code`)
Run Code Online (Sandbox Code Playgroud)

但现在的问题是,我错了csv格式,它实际上是4个代码,然后是换行符,所以fhroflg,qporlfg,vcalpfx,rplfigc,
vapworf,flofigx,apqoeei,clxosrc,
...

所以我需要能够指定两个LINES TERMINATED BY
这个问题已经扩展到了这里.


更新3使用
设置它来执行20k行的批量插入

while (!feof($file_handle)) {
   $val[] = fgetcsv($file_handle);
   $i++;
   if($i == 20000) {
      //do insert
      //set $i = 0;
      //$val = array();
   }
}

//do insert(for last few rows that dont reach 20k
Run Code Online (Sandbox Code Playgroud)

但它在此时死亡,因为由于某种原因,$ val包含75k行,并且想法为什么?
注意上面的代码是简化的.

小智 21

我怀疑这将是流行的答案,但我会让你的PHP应用程序在csv文件上运行mysqlimport.当然,它的优化远远超出了你在php中所做的.

  • 啊,经典的"我将为此投降".这个策略跟我有关:+1. (9认同)