【问题标题】:Timeout importing huge txt in mysql在mysql中导入巨大的txt超时
【发布时间】:2013-12-10 21:24:38
【问题描述】:

我正在尝试在 mysql 中导入一个巨大的 txt。
这是我第一次尝试使用 php 和 mysql,所以我不确定问题出在哪里。
我有一个将近 400 万行的 txt,我需要将其存储在数据库中。
我写了这段 php 来完成这项工作:

$con=mysqli_connect('localhost', 'root', 'root', 'commuting');
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }


$handle = fopen("matrix_pendo2001.txt", "r") or die("Couldn't get handle");
if ($handle) {
    while (!feof($handle)) {

        $line = fgets($handle, 4096);

        $a = substr($line,0,3);
        $b = substr($line,4,3);
        $c = substr($line,8,1);
        $d = substr($line,10,1);
        $e = substr($line,12,1);
        $f = substr($line,14,3);
        $g = substr($line,18,3);
        $h = substr($line,22,3);
        $i = substr($line,26,1);
        $l = substr($line,28,2);
        $m = substr($line,31,1);
        $n = substr($line,33,1);
        $o = substr($line,35,8);

        $sql="INSERT INTO ita (ProvRes, ComRes, Sesso, Motivo, Luogo, ProvLav, ComLav, StatExt, MercPrev, Mezzo, Ora, Tempo, Num)
        VALUES 
        ('$a', '$b', '$c', '$d', '$e', '$f', '$g', '$h', '$i', '$l', '$m', '$n', '$o')";

        if (!mysqli_query($con,$sql))
          {
          die('Error: ' . mysqli_error($con));
          }
        echo "record '<b>" . $line . "'</b> added. <br/>";

    }
    fclose($handle);
}
mysqli_close($con); 

脚本似乎运行良好,但我无法获取数据库中的所有行。
不到 100 万,脚本结束,没有明显错误。
我已将 max_execution_time 设置为 0,并将 memory_limit 增加到 2048MB,但没有任何变化。

【问题讨论】:

  • 你是通过命令行运行的吗?
  • 不要这样做。事实上,根本不要使用 PHP。查看MySQL Reference 中的LOAD DATA INFILE。它会更快、更可靠地完成工作。
  • 我没有在终端运行代码,我只是在浏览器中加载php页面。我现在正在尝试使用 LOAD DATA INFILE(查看 mcuadors 的答案)但仍然无法正常工作。

标签: php mysql mysqli timeout


【解决方案1】:

我建议你使用 LOAD DATA INFILE,这个 SQL 命令可以直接在服务器中执行,避免超时,并且是最快的方式,因为在 localhost 中运行。

这是一个小例子:

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test
  FIELDS TERMINATED BY ','  LINES STARTING BY 'xxx';

基于这个问题:loading-fixed-width-space-delimited-txt-file-into-mysql 你可以试试这个可能的解决方案:

LOAD DATA LOCAL INFILE 
'/yourfile.txt' 
INTO TABLE clip
(@row)
SET a = TRIM(SUBSTR(@row,0,3)),
    b = TRIM(SUBSTR(@row,4,3)),
    c = TRIM(SUBSTR(@row,10,1)),
    ......
;

【讨论】:

  • 问题是文件是一个没有分隔符的txt,但有修复列:首先开始一个0字符;第二个在 4,第三个在 8 等等(参见 substring 变量)。前行如下所示:“001 001 1 1 1 001 001 1 06 1 1 2”
  • 我明白了,然后先修复 CSV,然后使用 LOAD DATA,速度会快很多倍。我保证是更好的方法。
  • 如何将我的 txt 转换为有效的 CSV?以及如何使用加载数据?
  • 不...有什么问题...查询速度超快,但它生成1192条记录,并且存储的数据不是txt中的数据...这似乎是一些编码问题。这里是截图dropbox.com/s/bhn3fzoqmw0r52a/…
  • 我删除了文件并制作了一个新的副本,现在查询工作了!!!导入 3870728 行仅需 68.5925 秒。查询中的唯一错误是 SUBSTR,因为计数从 1 开始,而不是从 0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
  • 2015-05-04
  • 2013-08-12
  • 2013-07-03
相关资源
最近更新 更多