2014-01-24 45 views
2

我有一個使用Doctrine2 ORM的Symfony2應用程序。Doctrine2 ORM - 需要很長時間的持久性操作

我想從XML文件創建實體,然後堅持實體。典型的XML文件可能包含需要保持的幾千條記錄。 XML中的每條記錄都不會直接映射到單個實體上,而是映射到實體上,然後映射到一對多關係「多」端的其他實體。

我可以從XML元素創建實體,但它涉及在實體上運行「持久化」,每個操作在我的機器上需要大約2秒。從XML文件導入數千條記錄,這對我們的需求來說太慢了。

任何人都可以提供任何幫助嗎?

+0

這是工作的方式是建立在一個陣列被保留和儲存所有實體。一旦XML文件被讀取,它就會遍歷數組,並在每個實體上運行「持久化」。然後它稱爲「沖洗」。我現在意識到這不是最好的方法。它應該在創建時保留每個實體,然後定期刷新。 –

回答

0

請參閱Batch Processing in Doctrine documentation。想法是在每個新實體上調用persist(),但只有在一組n實體持續存在後才使用flush()。對於每個實體來說,花費的時間要少於撥打persist(),然後flush()

例如:

$batchSize = 20; 
for ($i = 1; $i <= 10000; ++$i) { 
    $user = new CmsUser; 
    $user->setStatus('user'); 
    $user->setUsername('user' . $i); 
    $user->setName('Mr.Smith-' . $i); 
    $em->persist($user); 
    if (($i % $batchSize) === 0) { 
     $em->flush(); 
    } 
} 

我刪除clear()因爲它會脫離所有實體。例如,如果您將foreach() {}與實體配合使用,則會出現問題,因爲Doctrine2會分離實體,因此循環將爲中斷

沒有使用clear(),Doctrine2在內存中保留所有持久化的實體,如果它佔用的內存比PHP可以使用的更多,它可能會導致錯誤。

如果您在循環中對Doctrine存儲庫以外的內容進行迭代,則可以在flush()之後調用clear()

0

感謝您的幫助。

以下是我如何更快地工作;

在創建並保存了20個實體後,我在實體管理器上調用了flush()和clear()。這就意味着需要鏈接到我創建的實體的相關實體已經失去了教條,所以需要從數據庫中重新加載。

現在需要爲每個實體周圍0.02秒 - 這不正是閃電快,但要快得多