2013-11-04 55 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

問題是,對於每個寄存器,我必須讀另一個表記得嗎?所以,問題仍在繼續。 –