我有两个胆石:
Voucher
Support这些实体有一个名为
voucher_support当我向新凭证添加1000个现有支持时,它将在voucher_support上调用1000个插入查询到我的SQL server。当然有50.000块也有50.000块。
我如何才能实现这一原则,只做一个插入,并提高我的性能?
编辑:
我认为批量插入不是解决办法。以下是我目前的代码,以便更好地理解:
$voucher = new Voucher();
$voucher->setCreatedAt(new \DateTime());
$supports = $this->em->getRepository('Support')->getOpen();
foreach($supports as $support){
// this generates for each support a INSERT in join table.
$voucher->addSupport($support);
}
$this->em->persist($voucher);
$this->em->flush();发布于 2017-05-30 09:58:22
阅读散装插入部分的Doctrine2文档。它建议对每一个“批”使用flush()。您还应该考虑用事务包装它。
<?php
$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();
$em->clear(); // Detaches all objects from Doctrine!
}
}
$em->flush(); //Persist objects that did not make up an entire batch
$em->clear();发布于 2017-05-30 10:04:03
Doctrine2不允许将多个INSERT语句组合为一个:
有些人似乎想知道为什么Doctrine不使用多重插入(insert into (.)值(.),.
首先,这种语法只支持mysql和较新的postgresql版本。其次,在使用AUTO_INCREMENT或串行和ORM需要标识符来管理对象的身份时,在这样的多插入中获取所有生成的标识符是不容易的。最后,插入性能很少是ORM的瓶颈。对于大多数情况,普通插入都足够快,如果您真的想做快速批量插入,那么无论如何多插入并不是最好的方法,例如Postgres复制或Mysql加载数据INFILE要快几个数量级。
这就是为什么不值得在ORM中实现在mysql和postgresql上执行多个插入的抽象。您可以在这里阅读有关Doctrine2批处理的更多信息:http://www.doctrine-project.org/blog/doctrine2-batch-processing.html
您可以切换到DBAL,也可以通过在一定数量的插入之后刷新实体管理器,以小批方式处理数据:
$batchSize = 20;
foreach ($items as $i => $item) {
$product = new Product($item['datas']);
$em->persist($product);
// flush everything to the database every 20 inserts
if (($i % $batchSize) == 0) {
$em->flush();
$em->clear();
}
}
// flush the remaining objects
$em->flush();
$em->clear();https://stackoverflow.com/questions/44258755
复制相似问题