2013-11-04 23 views
2

我正在做一个导入模块批量插入90000 +与symfony /学说注册。为了插入每个对象,我必须从其他表中读取一个字段。 因此,对于每个注册我第一次从另一个表获得相关的对象,像这样:从其他表的数据主义批量插入

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

把它放在新的对象,我想写的话写出来,像这样:

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

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

感谢

回答

3

学说将持有全部标识图(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了解更多信息。

+1

也许测试应该是'(($ index%1000)== 0)'? '($ index == 1000)'测试只会是真实的。 –

+0

@ n.1你绝对正确,我已经更新了答案 – AlexP

+0

问题是,对于每个寄存器,我必须读另一个表记得吗?所以,问题仍在继续。 –