简体   繁体   English

使用php将csv数据导入mysql数据库

[英]csv data import into mysql database using php

Hi I need to import a csv file of 15000 lines. 嗨,我需要导入15000行的csv文件。 I m using the fgetcsv function and parsing each and every line.. But I get a timeout error everytime. 我使用fgetcsv函数并解析每一行..但我每次都会收到超时错误。 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. 错误1:致命错误:第175行超过30秒的最长时间限制。

Error 2 : 错误2:

You have an error in your SQL syntax; 您的SQL语法有错误; check the manual that corresponds to your MySQL server version for the right syntax to use near 'S',0,0)' at line 1 检查与MySQL服务器版本对应的手册,以便在第1行的'S',0,0)附近使用正确的语法

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.. 该文件每次都是部分导入的..大约200 300行中的200 300行。

Set this at the top of the page: 将其设置在页面顶部:

set_time_limit ( 0 )

It will make the page run endlessly. 它将使页面无休止地运行。 However, that is not recommended but if you have no other option then cant help! 但是,不建议这样做,但如果您没有其他选择,那么无法帮助!

You can consult the documentation here . 您可以在此处查阅文档

To make it faster, you need to check your the various SQL you are sending and see if you have proper indexes created. 为了加快速度,您需要检查要发送的各种SQL,并查看是否创建了正确的索引。

If you are calling user defined functions and these functions are referring to global variables, then you can minimize the time take even more by passing those variables to the function and change the code so that the function refers to those passed variables. 如果您正在调用用户定义的函数并且这些函数引用全局变量,那么您可以通过将这些变量传递给函数并更改代码以使函数引用那些传递的变量来最小化时间。 Referring to global variables is slower than local variables. 引用全局变量比局部变量慢。

You can build a batch update string for every 500 lines of csv and then execute it at once if you are doing the mysql inserts on each line. 您可以为每500行csv构建一个批量更新字符串,然后如果您在每行上执行mysql插入,则立即执行它。 It'll be faster. 它会更快。

Another solution is to read the file with an offset: 另一种解决方案是使用偏移量读取文件:

  1. Read the first 500 lines, 阅读前500行,
  2. Insert them to the database 将它们插入数据库
  3. Redirect to csvimporter.php?offset=500 重定向到csvimporter.php?offset = 500
  4. Return the 1. step and read the 500 lines starting with offset 500 this time. 返回1.步骤并读取此次以偏移500开始的500行。

Another solution would be setting the timeout limit to 0 with: 另一种解决方案是将超时限制设置为0,其中:

set_time_limit(0);

You can make use of LOAD DATA INFILE which is a mysql utility, this is much faster than fgetcsv 您可以使用LOAD DATA INFILE这是一个mysql实用程序,这比fgetcsv快得多

more information is available on 有关更多信息,请访问

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

只需使用此@在php导入页面的开头

ini_set('max_execution_time',0);

If this is a one-time exercise, PHPMyAdmin supports Import via CSV. 如果这是一次性练习,PHPMyAdmin支持通过CSV导入。 import-a-csv-file-to-mysql-via-phpmyadmin 进口-A-CSV文件到MySQL-通路的phpmyadmin

He also notes the user of leveraging MySQL's LOAD DATA LOCAL INFILE . 他还指出用户利用MySQL的LOAD DATA LOCAL INFILE This is a very fast way to import data into a database table. 这是将数据导入数据库表的一种非常快速的方法。 load-data Mysql Docs link load-data Mysql Docs链接

EDIT: 编辑:

Here is some pseudo-code: 这是一些伪代码:

// 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);

Obviously, you need to ensure good SQL practices to prevent injection, etc. 显然,您需要确保良好的SQL实践以防止注入等。

PROBLEM: 问题:
There is a huge performance impact on the way you INSERT data into your table. 将数据插入表中的方式会对性能产生巨大影响。 For every one of your records you send an INSERT request to the server, 15000 INSERT requests that's huge! 对于你的每条记录,你向服务器发送一个INSERT请求,15000 INSERT请求是巨大的!

SOLUTION: : 解决方案
Well you should group your data like the way mysqldump does. 那么你应该像mysqldump那样对你的数据进行分组。 In your case you just need three insert statement not 15000 as below: 在您的情况下,您只需要三个插入语句而不是15000,如下所示:

before the loop write: 在循环写入之前:

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

And inside the loop concatenate the records to the query as below: 在循环内部将记录连接到查询,如下所示:

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

Inside the loop check that the counter is equal to 5000 OR 10000 OR 15000 then insert data to the vpireprot table and then set the $q to INSERT INTO... again. 在循环内部检查计数器是否等于5000或10000或15000然后将数据插入vpireprot表,然后再次将$ q设置为INSERT INTO...
run the query and enjoy!!! 运行查询,享受!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM