使用php批量将数据插入到MySQL数据库

3

我有成千上万条数据,这些数据从大型XML文件中解析出来,需要使用PHP和MySQL插入到数据库表中。我的问题是将所有数据插入表格太耗时了。是否有一种方式可以将我的数据分成较小的组,以便插入过程是按组进行的?如何设置一个脚本,使其每次处理100条数据?以下是我的代码:

foreach($itemList as $key => $item){
     $download_records  = new DownloadRecords();
    //check first if the content exists
    if(!$download_records->selectRecordsFromCondition("WHERE Guid=".$guid."")){
         /* do an insert here */
    } else {
         /*do an update */
    }

}

*注意:$itemList约为62,000个,且仍在增长。

3个回答

3

使用for循环吗?

但是,将数据快速加载到MySQL中的最快选项是使用LOAD DATA INFILE命令,您可以通过PHP创建要加载的文件,然后通过不同的过程(或作为原始过程的最后一步)将其提供给MySQL。

如果无法使用文件,请使用以下语法:

insert into table(col1, col2) VALUES (val1,val2), (val3,val4), (val5, val6)

所以你可以减少要运行的句子总数。

编辑:根据你的片段,似乎你可以从MySQL的INSERT ... ON DUPLICATE KEY UPDATE语法中受益,让数据库来完成工作并减少查询次数。这假设你的表具有主键或唯一索引。

为了每100行命中DB,你可以做类似以下的事情(请检查并将其修复到您的环境

$insertOrUpdateStatement1 = "INSERT INTO table (col1, col2) VALUES ";
$insertOrUpdateStatement2 = "ON DUPLICATE KEY UPDATE ";
$counter = 0;
$queries = array();

foreach($itemList as $key => $item){
    $val1 = escape($item->col1); //escape is a function that will make 
                                 //the input safe from SQL injection. 
                                 //Depends on how are you accessing the DB

    $val2 = escape($item->col2);

    $queries[] = $insertOrUpdateStatement1. 
    "('$val1','$val2')".$insertOrUpdateStatement2.
    "col1 = '$val1', col2 = '$val2'";

    $counter++;

    if ($counter % 100 == 0) {
        executeQueries($queries);
        $queries = array();
        $counter = 0;
    }
}

executeQueries会获取数组并发送一个多个查询:

function executeQueries($queries) {
   $data = "";
     foreach ($queries as $query) {
        $data.=$query.";\n";
    }
    executeQuery($data);
}

是的,我正在使用for循环将数据插入远程数据库。问题在于我正在使用远程数据库,因此我的脚本正在运行在单独的服务器上,以提供给另一个运行在单独服务器上的数据库。 - text
使用尽可能少的语句,即使用大型插入语句。 - Vinko Vrsalovic
是的,我可以使用文件,这就是我的计划。我有一个关注点,如何在达到100行后重复插入到表(列)VALUES(val)? - text
使用取模运算符。for ($i = 0; $i < $rows; $i++) { $row.= addvaluestorow(); if ($i % 100 == 0) { sendrow($row); $row = ""; } } - Vinko Vrsalovic
我看到你正在使用foreach,添加一个外部计数器。 - Vinko Vrsalovic

0

是的,只需按照您预期的方式操作即可。

如果您认为可能会遇到超时等问题,则不应尝试从 Web 应用程序进行批量插入。相反,将文件放在某个地方,并让守护进程或 cron 等程序获取并运行批处理作业(如果从 cron 运行,请确保同时只运行一个实例)。


0

为避免超时(或用户失去网络连接),您应该将其放在临时目录中,并使用cron作业处理文件。

仅使用Web进行上传。

如果您真的想在Web请求中导入到DB,可以执行批量插入或至少使用一个事务,这应该更快。

然后,按100个一组限制插入(如果计数器为count%100 == 0,则提交您的事务),并重复直到插入所有行。


如何实现 $count%100=0?我使用一个文件将数据转储到我的目标表中。INSERT INTO table VALUES(val), (val).... (val); 并在行数达到 100 或其他值后重复执行 INSERT? - text
cnx = mysql_connect() x=0 while (something to insert) do : fetch_values_from_file(X,Y,Z) cnx.exec("insert into table values X,Y,Z",X, Y,Z) x += 1 if x % 100 : cnx.commit() - makapuf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接