Optimization Symfony2,条令,添加\插入\更新针对大量查询的最佳解决方案
让我们假设我们有以下代码:Optimization Symfony2,条令,添加\插入\更新针对大量查询的最佳解决方案,optimization,symfony,doctrine-orm,Optimization,Symfony,Doctrine Orm,让我们假设我们有以下代码: while (true) { foreach($array as $row) { $item = $em->getRepository('reponame')->findOneBy(array('filter')); if (!$item) { $needPersist = true; $item = new Item(); }
while (true)
{
foreach($array as $row)
{
$item = $em->getRepository('reponame')->findOneBy(array('filter'));
if (!$item)
{
$needPersist = true;
$item = new Item();
}
$item->setItemName()
// and so on ...
if ($needPersist)
{
$em->persist();
}
}
$em->flush();
}
所以,关键是代码将被执行很多次(而服务器不会死掉:)。我们想优化它。每次我们:
PS:DB中的每个条目都有几个列(不仅仅是ID)是唯一的。无论更新后是否需要它们保持不变,从数据库中检索10k+及以上条目并将其水合为php对象都需要太多内存。在这种情况下,您最好回退到并触发纯SQL查询
$allResults = ...
->where("o.id IN (:ids)")->setParameter("ids", $ids)
->getQuery()
->getResults() ;
虽然在处理10000条记录(不知道,从未测试过)时这仍然很慢,但是有两个大的查询要比10000个小的查询快得多。您的代码缺少一些细节-如果不仅仅是id,哪些数据标识条目?新条目的数据来自哪里?-,有一些错误(?)-
findOneBy(数组('filter'))
和$item->setItemName()
-为什么while(true))
?您的查询似乎只保留新项目。一些现有项目是否也需要更新?如果条目不仅仅由id标识,那么主键由哪些列组成。这听起来很像任何优化的起点。虽然(正确)-为了表明它可以从100万循环到100万循环(这是一般的例子),数据来自函数中的大量数据。是的,但点并没有错误,我在调用此代码之前检查它。表有4-5列(我不认为有多少列)。是,代码为“更新现有,如果不添加新”。现在主要是id+action(string),但我反对它,因为Symfony提倡面向对象的方法,使用dbal和数组至少在我看来是错误的。Imo更好的解决方案是延迟这些任务,并使用JobQueue/worker或类似的方法将它们与实际请求分离。通过这种方式,您可以保留(希望经过测试的)模型/实体、验证、DI等的所有symfony优点,而不必诉诸粗糙的黑客。请考虑一下可怜的灵魂,他们可能需要筛选您的“优化”脚本以查找bug或更改某些sql;)我在我的实际项目中这样做。所有这些都在symfony框架中(作为控制台命令),但使用dbal。尽管cli可以无限时间运行,但有数百万个数据库条目,orm/odm会占用您所有的内存并卡住。这是在一台有GB内存的机器上实现的。