假设我们有这段代码:
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();
}
所以,重点是代码将被执行很多次(而服务器不会死掉:))。我们想要优化它。每次我们:
所以问题是 - 如何避免不必要的查询并优化“检查条目是否存在”?因为当有 100-500 个查询时,它并没有那么可怕......但是当一个 while 循环达到 1000-10000 个查询时 - 就太多了。
PS:数据库中的每个条目在几列中都是唯一的(不仅仅是 ID)。
例如。 假设您的过滤器想要加载 ids 1, 2, 10。所以 QB 会是这样的:
$allResults = ...
->where("o.id IN (:ids)")->setParameter("ids", $ids)
->getQuery()
->getResults() ;
“foreach”这些结果,完成更新和刷新它们的工作
在执行该循环时,将这些获取的对象的 id 保存在新数组中
使用 array_diff 将该数组与原始数组进行比较。现在你有了第一次未获取的 id
冲洗并重复:)
不要忘记 $em->clear() 来释放内存
虽然在处理 10.000 条记录时仍然会很慢(不知道,从未测试过),但 2 个大查询会比 10.000 个小查询快得多。
无论更新后是否需要它们保留,从数据库检索 10k+ 及以上条目并将它们合并到 php 对象将需要太多内存。在这种情况下,您应该更好地回退到 Doctrine DBAL Layer 并触发纯 SQL 查询。