我需要从csv文件导入大数据(大约1m条记录)。为了避免内存泄漏,我尝试从条令文档中批量插入:
$batchSize = 20;
for ($i = 1; $i <= 10000; ++$i) {
//code
$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();
问题是我的插入包含"多对一"关系,每次我使用clear()对象时都会重复该关系中的条目。
是否有可能分离实体并避免重复?
是的。您需要执行智能清理。这意味着您提供了要清除的实体类型。示例:
$em->clear(SomeEntity::class);
$em->clear(OtherEntity::class);
这将只从EM中删除那些类型,而保留所有其他类型。通过这种方式,您可以重用那些其他对象。
使用ORM导入大数据非常耗时和占用内存。我从来没有找到一种方法来快速而理智地引入教义。除了我这样做的进口,还有一个PITA需要维护。
经过多年的数据导入,我发现最有效的方法是:
- 临时表中的CSV导入(MySQL中的LOAD DATA INFILE或pgsql中的COPY)
- 进行插入或更新查询(在MySQL中插入INTO.SELECT..ON DUPLICATE KEY)
- 根据复杂程度在SQL或PHP中执行更具体的操作
通过这种方式,我可以在几秒钟内导入十几个大的CSV文件。
希望能有所帮助。