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

发布于 2024-07-25 05:48:52 字数 517 浏览 8 评论 0原文

我使用 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 个,并且仍在增长。

I have a thousands of data parsed from huge XML to be inserted into database table using PHP and MySQL. My Problem is it takes too long to insert all the data into table. Is there a way that my data are split into smaller group so that the process of insertion is by group? How can set up a script that will process the data by 100 for example? Here's my code:

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 */
    }

}

*note: $itemList is around 62,000 and still growing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云仙小弟 2024-08-01 05:48:52

使用for循环?

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

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

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

这样您就可以减少要运行的句子总数。

编辑:鉴于您的代码片段,您似乎可以从 INSERT ... ON DUPLICATE 中受益MySQL的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);
}

Using a for loop?

But the quickest option to load data into MySQL is to use the LOAD DATA INFILE command, you can create the file to load via PHP and then feed it to MySQL via a different process (or as a final step in the original process).

If you cannot use a file, use the following syntax:

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

so you reduce to total amount of sentences to run.

EDIT: Given your snippet, it seems you can benefit from the INSERT ... ON DUPLICATE KEY UPDATE syntax of MySQL, letting the database do the work and reducing the amount of queries. This assumes your table has a primary key or unique index.

To hit the DB every 100 rows you can do something like (PLEASE REVIEW IT AND FIX IT TO YOUR ENVIRONMENT)

$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;
    }
}

And executeQueries would grab the array and send a single multiple query:

function executeQueries($queries) {
   $data = "";
     foreach ($queries as $query) {
        $data.=$query.";\n";
    }
    executeQuery($data);
}
花开半夏魅人心 2024-08-01 05:48:52

是的,只要做你期望做的事。

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

Yes, just do what you'd expect to do.

You should not try to do bulk insertion from a web application if you think you might hit a timeout etc. Instead drop the file somewhere and have a daemon or cron etc, pick it up and run a batch job (If running from cron, be sure that only one instance runs at once).

东风软 2024-08-01 05:48:52

您应该像前面所说的那样将其放在临时目录中,并使用 cron 作业来处理文件,以避免超时(或用户丢失网络)。

仅使用网络进行上传。

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

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

You should put it as said before in a temp directory with a cron job to process files, in order to avoid timeouts (or user loosing network).

Use only the web for uploads.

If you really want to import to DB on a web request you can either do a bulk insert or use at least a transaction which should be faster.

Then for limiting inserts by batches of 100 (commiting your trasnsaction if a counter is count%100==0) and repeat until all your rows were inserted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文