首页 > 解决方案 > 如何有效地将批量数据集插入mysql数据库

问题描述

我对 symfony5 命令类以及如何有效地插入 ca 有一些疑问。1000 万个条目(只有一个具有 Uuid 字段且与其他实体没有任何关系的实体)。整个噱头没有任何目的,只是为了使用 elasticsearch 运行一些测试才需要。

现在,在插入数据时,到目前为止一切正常,但持续了几个小时(20k / h)。

    for ($i = 0; $i < $numberOfVochers; $i++) {

        $voucher = new Voucher();
        $voucher->setCode(Uuid::v4());
        $voucher->setValid(new DateTime());
      
        $this->em->persist($voucher);
        $this->em->flush();
    }

我应该做什么(除了摆脱我的硬件:Macbook Pro 2,3 GHz Intel Core i5, 8GB)来更快地完成这项工作?

标签: phpmysqldoctrinecommandsymfony5

解决方案


一方面,您可能应该执行批量更新,例如:

for ($i = 0; $i < $numberOfVochers; $i++) {
    $voucher = new Voucher();
    $voucher->setCode(Uuid::v4());
    $voucher->setValid(new DateTime());
      
    $this->em->persist($voucher);
    if ($i % 100) {
        $this->em->flush();
    }
}
$this->em->flush(); // just in case the last badge was not added

此外,您应该$this->em->clear()在每次刷新后调用,以确保您不会遇到内存问题。在您的情况下$voucher,不依赖于先前插入的数据,因此clear()不应造成任何问题。

由于此操作是批量执行的,您现在可以更新您的命令以对创建进行分区,也就是说,您可以为 1/4 的凭证启动该过程 4 次,而不是为所有凭证调用一次命令。然后你有 4 个进程在执行插入,这通常会提高性能,因为每个进程都可以在不同的处理器上运行。在您的情况下,由于可以独立创建每个凭证,因此这应该不是很多工作。在其他情况下,您可能必须定制您的命令才能正确划分工作。

或者,您也可以在命令中使用线程(不能推荐)或使用诸如 messenger 之类的东西将任务分成多个批次,为每个批次发送一条消息,然后使用多个工作人员来处理这些消息。


推荐阅读