使用其他表中的数据插入Doctrine批处理

时间:2013-11-04 12:45:55

标签: php symfony doctrine-orm

我正在做一个导入模块,批量插入90000个寄存器和symfony / doctrine。为了插入每个对象,我必须从其他表中读取一个字段。 因此,对于每个寄存器,我首先从另一个表中获取相关对象,如下所示:

$this->doctrine->getRepository('table1')

把它放在我想写的新对象中,然后写出来,就像这样:

$em = $this->doctrine->getManager();
$em->merge($newObject);
$em->flush();

(我使用merge,因为它是保存现有和新对象的一般方法) 但即使我设置apache进行漫长的等待(这是不可取的),这需要花费太多时间和响应超时。 Doctrine_Collection方法也不起作用。 任何人都知道一种更好的方法,以便在合理的时间内返回吗?

由于

1 个答案:

答案 0 :(得分:3)

Doctrine将在身份映射中保存所有托管实体实例(UnitOfWork) - 这意味着任何计划保留(在flush()上)的实体都将保留在内存中。如果您执行大量插入操作,这可能会成为性能杀手。

相反,持久/保存一个实例然后每次调用flush将导致每个实体至少有一个INSERT/UPDATE - 由于不需要的数据库查询,这将再次影响性能。

您应该考虑将所需的插入分解为较小的块,并允许实体管理器释放任何内存实例:

foreach($entities as $index => $entity) {
  $entity->setFoo('bar'); 
  $objectManager->merge($entity);

  if (($index % 1000) == 0) {
    $entityManager->flush(); // Flush the changes every 1000 iterations
    $entityManager->clear(); // Clear all managed entities
  }
}

您提到的Doctrine_Collection实际上适用于Doctrine 1,并且从那时起已经发生了很多变化。

您应该查看Doctrine 2 documentation on batch processing以获取更多信息。