3

Hi I need to import a csv file of 15000 lines. I m using the fgetcsv function and parsing each and every line.. But I get a timeout error everytime. The process is too slow and data is oly partially imported. Is there any way out to make the data import faster and more efficient?

if(isset($_POST['submit']))
{

 $fname = $_FILES['sel_file']['name'];
 $var = 'Invalid File';
 $chk_ext = explode(".",$fname);

 if(strtolower($chk_ext[1]) == "csv")
 {

     $filename = $_FILES['sel_file']['tmp_name'];
     $handle = fopen($filename, "r");
 $res = mysql_query("SELECT * FROM vpireport");
 $rows = mysql_num_rows($res);
 if($rows>=0)
{
    mysql_query("DELETE FROM vpireport") or die(mysql_error());

    for($i =1;($data = fgetcsv($handle, 10000, ",")) !== FALSE; $i++)
    {
        if($i==1)
        continue;
        $sql = "INSERT into vpireport
                                (item_code,
                                 company_id,
                                 purchase,
                                 purchase_value) 
                                 values
                                (".$data[0].",
                                 ".$data[1].",
                                 ".$data[2].",
                                 ".$data[3].")";
        //echo "$sql";
        mysql_query($sql) or die(mysql_error());
    }
}

 fclose($handle);
?>
 <script language="javascript">
 alert("Successfully Imported!");
 </script>
 <?

} The problem is everytime it gets stuck in between the import process and displays the following errors:

Error 1 : Fatal Error: Maximum time limit of 30 seconds exceeded at line 175.

Error 2 :

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'S',0,0)' at line 1

This error I m not able to detect...

The file is imported oly partial everytime.. oly around 200 300 lines out of a 10000 lines..

4

6 回答 6

3

在页面顶部设置:

set_time_limit ( 0 )

它将使页面无休止地运行。但是,不建议这样做,但如果您别无选择,那就无能为力了!

您可以在此处查阅文档

为了让它更快,您需要检查您发送的各种 SQL 并查看您是否创建了正确的索引。

如果您正在调用用户定义的函数并且这些函数引用全局变量,那么您可以通过将这些变量传递给函数并更改代码以使函数引用那些传递的变量来最小化所花费的时间。引用全局变量比引用局部变量慢。

于 2012-05-19T06:10:44.487 回答
3

您可以为每 500 行 csv 构建一个批量更新字符串,然后如果您在每行上执行 mysql 插入,则立即执行它。它会更快。

另一种解决方案是读取带有偏移量的文件:

  1. 阅读前 500 行,
  2. 将它们插入数据库
  3. 重定向到 csvimporter.php?offset=500
  4. 返回 1. 步骤,这次读取从偏移量 500 开始的 500 行。

另一种解决方案是将超时限制设置为 0:

set_time_limit(0);
于 2012-05-19T06:15:07.983 回答
2

您可以使用 LOAD DATA INFILE 这是一个 mysql 实用程序,这比 fgetcsv 快得多

更多信息可在

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

于 2012-05-19T06:26:06.613 回答
1

只需在您的 php 导入页面的开头使用这个 @

ini_set('max_execution_time',0);
于 2012-05-19T06:21:11.687 回答
1

如果这是一次性练习,PHPMyAdmin 支持通过 CSV 导入。 导入-a-csv-file-to-mysql-via-phpmyadmin

他还指出了利用 MySQL 的用户LOAD DATA LOCAL INFILE。这是一种将数据导入数据库表的非常快速的方法。加载数据 Mysql Docs 链接

编辑:

这是一些伪代码:

// perform the file upload 
$absolute_file_location = upload_file();

// connect to your MySQL database as you would normally
your_mysql_connection();

// execute the query
$query = "LOAD DATA LOCAL INFILE '" . $absolute_file_location . 
         "' INTO TABLE `table_name`
         FIELDS TERMINATED BY ','
         LINES TERMINATED BY '\n'
         (column1, column2, column3, etc)";
$result = mysql_query($query);

显然,您需要确保良好的 SQL 实践以防止注入等。

于 2012-05-19T06:23:14.743 回答
1

问题:
将数据插入表的方式对性能有巨大影响。对于您的每一条记录,您都会向服务器发送一个 INSERT 请求,15000 个 INSERT 请求是巨大的!

解决方案: :
你应该像 mysqldump 那样对数据进行分组。在您的情况下,您只需要三个插入语句而不是 15000,如下所示:

在循环之前写:

$q = "INSERT into vpireport(item_code,company_id,purchase,purchase_value)values";

并在循环内将记录连接到查询,如下所示:

$q .= "($data[0],$data[1],$data[2],$data[3]),";

在循环内部检查计数器是否等于 5000 OR 10000 OR 15000 然后将数据插入vpireprot表中,然后INSERT INTO...再次将 $q 设置为。
运行查询并享受!

于 2012-05-19T07:52:39.023 回答