3

我使用 PHP 和 MySQL 从巨大的 XML 中解析出数千个数据,并将其插入到数据库表中。我的问题是将所有数据插入表中需要很长时间。有没有办法将我的数据分成更小的组,以便插入过程按组进行?例如,如何设置一个将数据处理 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 个并且还在增长。

4

3 回答 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 行访问一次数据库,您可以执行以下操作(请查看并修复您的环境

$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);
}
于 2009-06-25T07:00:06.157 回答
0

是的,只要做你想做的事。

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

于 2009-06-25T06:58:13.370 回答
0

您应该如前所述将其放在带有 cron 作业的临时目录中以处理文件,以避免超时(或用户失去网络)。

仅使用网络进行上传。

如果您真的想通过网络请求导入数据库,您可以进行批量插入或至少使用一个更快的事务。

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

于 2009-06-25T07:36:31.263 回答