Php 查询需要8小时来检查和插入300万个数据

Php 查询需要8小时来检查和插入300万个数据,php,mysql,laravel,eloquent,Php,Mysql,Laravel,Eloquent,我每天都会收到新的10000sxml文件数据 我总是运行一个查询,看看这些XML文件中是否有任何新数据,如果我们的数据库中不存在这些数据,那么将这些数据插入到我们的表中 这是密码 if(!Dictionary::where('word_code' , '=' , $dic->word_code)->exists()) { // then insert into the database. } 其中$dic->word_代码来自数千个XML文件。每次它逐个打开新的XML文件,

我每天都会收到新的10000sxml文件数据

我总是运行一个查询,看看这些XML文件中是否有任何新数据,如果我们的数据库中不存在这些数据,那么将这些数据插入到我们的表中

这是密码

if(!Dictionary::where('word_code' , '=' , $dic->word_code)->exists()) {
    // then insert into the database.
}
其中$dic->word_代码来自数千个XML文件。每次它逐个打开新的XML文件,然后检查该记录是否存在,然后打开一个新的XML文件并检查它是否不存在,然后插入该记录,然后移动到另一个文件,并对10000个XML文件执行相同的过程

每个XML文件大约为40到80mb,其中包含大量数据

到目前为止,我已经有了2981293行,并使用我的XML文件检查2981293行,然后插入该行似乎是一项非常耗时和资源贪婪的任务

word_代码已在索引中

目前的方法大约需要8小时来完成这个过程


顺便说一句,我必须提到的是,在运行这个8小时的庞大过程后,它每天下载大约1500到2000行数据。

我将把这项工作分为两个任务:

  • 使用PHP脚本将XML数据无条件加载到没有约束、没有主键、没有索引的临时表中。请确保在加载数据之前截断该表

  • 执行一条
    INSERT
    语句,将临时表中的记录合并到主表中,可能使用
    ON DUPLICATE KEY UPDATE
    IGNORE
    选项,或者使用负join子句。看

  • 对于第二点,您可以这样做:

    插入忽略
    进入主要
    选择*
    从温度;
    
    如果要比较的字段不是主表中的主键,或者没有唯一索引,则可能需要这样的语句:

    插入到主目录中
    选择温度*
    临时工
    左连接主m2
    在m2.word_代码=临时word_代码上
    其中m2.word_代码为空;
    

    但这比基于主键的解决方案要慢一些。

    将文件逐行与数据库进行比较是核心问题。文件系统和数据库都支持快速比较数百万行

    你有两个选择

    备选案文1: 保留上一个运行到运行文件系统的文件备份,比较以查找文件中的差异

    备选案文2:
    使用Load DATA INFILE将XML文件加载到MySQL表中。然后对所有行运行查询,以查找新行和更改的行。确保使用定义良好的唯一键对表进行索引,以保持此查询的效率。

    根据下面trincot的响应,如果结果表与XML格式匹配,则可以使用LOAD DATA Infle直接附加到结果表。但是,如果在发现新行时出现ETL过程或其他逻辑,则这可能不起作用。我的脚本每天都要比较这些xml文件,然后只插入新数据而忽略重复数据。正是因为有数千个xml文件,所以应该使用load data Infle将它们加载到数据库中。这种将数据加载到MySQL的方法比为每行执行多次插入要快得多。您可以将数据加载到暂存表中,然后比较差异,或者插入忽略。为什么要检查?我有很多重复,所以在插入之前必须确保。这不是一个很好的理由。您的模式应该可以防止重复,或者知道如何处理它。这更有意义,我将尝试一下,看看我得到了什么。有没有从临时表合并到主表并更新重复记录,但插入新记录的示例?请参阅,谢谢您的帮助。我看到您正在通过ID列映射记录。所以两个表中的ID必须相同,这是我能接受的最好的答案。完美的你把我送回学校了。