【问题标题】:PHP array to MYSQL insertion stops after 11,000 rowsPHP 数组到 MYSQL 的插入在 11,000 行后停止
【发布时间】:2015-08-17 15:33:13
【问题描述】:

目前,我通过从 URL 下载 csv 文件并使用 str_getcsv() 解析它来获取二维 PHP 数据数组。

之后,我循环遍历每一行并将值插入到相应的 SQL 列中:

foreach($array as $a=>$value){

    //defining variables

    $sql = "INSERT INTO Ranking (ra, na, sc, kd, wi, ki, de, sh, ti)
           VALUES ('$ra','$na','$sc','$kd','$wi','$ki','$de','$sh','$ti')";

    $conn->query($sql);
}

$conn->close();

我有大约 16,000 行数据,但奇怪的是,插入恰好在 10,999 行之后停止。大约 929 kb。

我找不到原因,因为我的托管服务提供商声明没有行数限制。我认为 PHP 文件的执行不会由于执行时间限制而停止,因为在此插入命令之后,数组也会存储在本地,并且会在文件下载后大约 4 秒发生。

foreach()-loop 是否有某种时间限制?它会在执行一定次数后停止吗?如果我只用一个 sql 查询连接一次,它会工作吗?

更新:

原来 sql 导入时间超过了。

Fatal error: Maximum execution time of 10 seconds exceeded
in /home/mainhost/public_html/phpMyAdmin/libraries/import/sql.php on line 118

(phpmyadmin中手动插入尝试的输出)

我该怎么办?将输入拆分为两个查询?

【问题讨论】:

  • 您是否显示 PHP 错误?他们什么都不告诉你? count($array) 的结果是否 > 10,999?
  • 天哪,您实际上是在循环插入?永远不要那样做。阅读this
  • 你确实有有限的执行时间和你可以使用的内存。从 CLI 运行此脚本以确定您的脚本是否正在死亡,或者它是否是处理器。
  • 我不显示错误,但由于文件路径不同,文件只能由服务器成功执行(cronjob)。我以后可以试试。而且我知道由于本地存储的文件长度> 10,999
  • @Andrew 我同意,但实际上可以让某人知道您知道的某事,而无需像他们不知道那样愚蠢。

标签: php mysql arrays limit


【解决方案1】:

我不知道以下内容是否有帮助 - 您可能需要对其进行调整,但如上所述,在循环中多次插入 ....

填充值数组后构建sql并执行一次。

$values=array();
foreach( $array as $a => $value ){
    $values[]="('$ra','$na','$sc','$kd','$wi','$ki','$de','$sh','$ti')";
}
$sql="INSERT INTO `Ranking` (`ra`,`na`,`sc`,`kd`,`wi`,`ki`,`de`,`sh`,`ti`)
      values ".implode( ','.PHP_EOL, $values ).";";

$conn->query( $sql );

【讨论】:

  • 这不是开箱即用的,但我会尝试调整它直到它成功。看起来很有前途!
【解决方案2】:

我知道这并不能直接回答您的问题,但更好的解决方法是:

$sql = '';

foreach($array as $a=>$value){

    //defining variables

    $sql .= "INSERT INTO Ranking (ra, na, sc, kd, wi, ki, de, sh, ti)
           VALUES ('$ra','$na','$sc','$kd','$wi','$ki','$de','$sh','$ti')";

}

$conn->query($sql);

$conn->close();

原因是您只有 1 次往返数据库。不管这是否只是一个本地连接,将您的插入批处理仍然更有效。这应该可以解决您同时看到的限制。

【讨论】:

  • 很遗憾,这没有执行。
  • 你不是在每个INSERT 查询之间缺少一个; 吗?
  • 对不起,你是对的。行应为: $sql .= "INSERT INTO Ranking (ra, na, sc, kd, wi, ki, de, sh, ti) VALUES ('$ra','$na','$sc','$ kd','$wi','$ki','$de','$sh','$ti');";
【解决方案3】:

想出了一个解决方案!

由于循环遍历所有行被证明不是正确的方法,并且查询整个数组超过了导入时间,我将它们组合起来,即一次导入 6000 行,这对我来说很好!

foreach($array as $a=>$value){
    $i += 1;
    if(!fmod($i / 6000, 1) == 1){
        $sql = substr($sql, 0, -1);
        $conn->query($sql);
        $sql = "INSERT INTO Ranking (rank, name, score, kd, wins, kills, deaths, shots, time) VALUES ";
    }

    //defining variables

    $sql .= "('$ra',' $na ','$sc','$kd','$wi','$ki','$de','$sh','$ti'),";
}

$sql = substr($sql, 0, -1);

祝你有美好的一天!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-11
    • 2014-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 2013-02-26
    • 1970-01-01
    相关资源
    最近更新 更多