我实际上是使用 Symfony 命令迁移数据
基本上,目标是选择我的应用程序中的所有身份(大约 100,000 个条目)并获取身份和名称,以便填充我的“identitie_name”表,该表具有“身份”字段(关系)和“名称” ' 字段(来自 Identitie 实体)
我的逻辑有效,但速度非常慢(我使用 php -d memory_limit=-1 bin/console my-command 调用我的命令)
这是我在存储库和命令中的逻辑,您有加快此过程的技巧吗?
命令.php
protected function execute(InputInterface $input, OutputInterface $output) {
$this->io = new SymfonyStyle($input, $output);
$identities = $this->identitieRepository->getAllIdentities();
$output->writeln('progressing...');
foreach($identities as $identitie) {
$this->insertIntoIdentitieName($identitie, $identitie->getName());
$this->entityManager->flush();
}
$this->io->success('good!');
return 0;
}
private function insertIntoIdentiteName($identitieId, $name) {
$identitieName = new IdentiteName();
$identitieName ->setIdentite($identitieId);
$identitieName ->setName($name);
$identitieName ->setActive(true);
$this->entityManager->persist($identitieName );
}
存储库.php
public function getAllIdentities()
{
$query = $this->getEntityManager()->createQueryBuilder()
->select('i')->from('App\Entity\Identitie', 'i')
->orderBy('i.id', 'DESC');
return $query->getQuery()->getResult();
}
您当前在 Symfony 中迁移数据的方法是有效的,但由于在循环内使用
$entityManager->flush()
,所以效率低下。这会导致 Doctrine ORM 为每个身份执行一个数据库事务,速度很慢。要优化此功能,您只需将 flush()
移到循环之外或使用批处理即可。
$i = 0;
$batchSize = 20;
foreach($identities as $identitie) {
$this->insertIntoIdentitieName($identitie, $identitie->getName());
if (($i % $batchSize) === 0) {
$this->entityManager->flush();
$this->entityManager->clear(); // Optionally, if you want to save some RAM
}
$i++;
}
$this->entityManager->flush();
$this->entityManager->clear();
有了这么大的数据集,我也会考虑从数据库中批量检索你的身份数据。