我正在使用Doctrine和MongoDB作为应用程序,并且有一项任务应该将CSV文件中的数据导入到集合中。大约有5种不同的CSV文件,每个文件至少有450.000个条目,每年应该重要1到3次。
目前,我遍历文件的所有行,创建一个对象,调用persist()
并刷新每个2.500项。
每个项目都不是很大,它有一个ID,一个10-20个字符的字符串,一个5-10个字符的字符串和一个布尔值。
我的第一个问题是: 当我冲洗每个5.000项时,插入速度明显变慢。在我的测试环境中,冲洗5.000件物品需要大约102秒,冲洗2.500件物品大约需要10秒钟。
一段时间后,法拉盛会变慢。如上所述,在开始时冲洗2.500件物品大约需要10秒钟,在完成100,000件物品后,冲洗2.500件物品需要将近一分钟。
我可以做些什么来加快速度吗?
答案 0 :(得分:2)
我认为您的脚本中有两个部分可以优化。
file_get_contents()
或file()
),或者通过chunck with { {1}},fopen()
。最后一个选项是首选,因为它只会在处理一堆行时占用必要的内存量。
fread()
已处理的对象,否则它将保留在内存中直到脚本结束。这意味着如果一个DC2对象使用1Mo内存,并且您有100,000个对象,则在脚本末尾将使用100,000Mo。
因此,按照2,500的范围对插入进行批处理是个不错的主意,但显然需要从EntityManager中删除已处理的对象。可以使用clear()
$entityManager->clear();
将清除整个clear()
,您想要清除单个实体,您可以使用EntityManager
。
如果您想了解您的内存使用情况,您可能也会对这些功能感兴趣
答案 1 :(得分:0)
这个导入脚本是否需要使用Doctrine ODM?对于整个应用程序 - 当然。但是处理大量开销的数据并不是最理想的,因为PHP在保存和处理大型集合方面效率不高。
您可以做的最佳优化是跳过该层并直接使用mongodb类,并确保您逐行读取文件而不是一次读取所有文件。如果您对MongoDB有一些网络延迟(但是您不需要将其推送到5k文档),那么使用batchInsert()会加快您的速度。