Php 条令数据装置:如何处理大型csv文件?

Php 条令数据装置:如何处理大型csv文件?,php,mysql,symfony,csv,doctrine-orm,Php,Mysql,Symfony,Csv,Doctrine Orm,我试图使用doctrine数据装置从一个“大”CSV文件(3Mo/37000行/7列)插入数据(在mySQL数据库中) 过程非常缓慢,此时我无法成功(可能是我不得不再等一点) 我认为条令数据装置不打算管理如此数量的数据?也许解决方案应该是直接将我的csv导入数据库 你知道怎么做吗 代码如下: 创建这样的大批量导入时要遵循两条规则: 禁用SQL日志记录:($manager->getConnection()->getConfiguration()->setSQLLogger(null);)以避免巨

我试图使用doctrine数据装置从一个“大”CSV文件(3Mo/37000行/7列)插入数据(在mySQL数据库中)

过程非常缓慢,此时我无法成功(可能是我不得不再等一点)

我认为条令数据装置不打算管理如此数量的数据?也许解决方案应该是直接将我的csv导入数据库

你知道怎么做吗

代码如下:


创建这样的大批量导入时要遵循两条规则:

  • 禁用SQL日志记录:(
    $manager->getConnection()->getConfiguration()->setSQLLogger(null);
    )以避免巨大的内存损失

  • 经常冲洗和清理,而不是最后只冲洗一次。我建议您在循环中添加
    if($I%25==0){$manager->flush();$manager->clear()}
    ,以便每插入25次就刷新一次


编辑:我忘记了最后一件事:当您不再需要实体时,不要将它们保存在变量中。这里,在循环中,您只需要正在处理的当前实体,因此不要将以前的实体存储在
$coordinaresfrcity
数组中。如果继续这样做,可能会导致内存溢出。

文档中有一个很好的例子:

使用模(x%y)表达式实现批处理,此示例将一次插入20。您可以根据您的服务器对此进行优化

$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();
$batchSize=20;
对于($i=1;$i setStatus('user');
$user->setUsername('user'.$i);
$user->setName('Mr.Smith-'。$i);
$em->persist($user);
如果($i%$batchSize)==0){
$em->flush();
$em->clear();//从条令中分离所有对象!
}
}
$em->flush();//保留未组成整个批处理的对象
$em->clear();

对于需要大量内存但互不依赖的装置,我通过使用append标志一次插入一个实体(或更小的实体组)来解决这个问题:

bin/console doctrine:fixtures:load --fixtures="memory_hungry_fixture.file" --append
然后我编写一个Bash脚本,根据需要多次运行该命令


在您的情况下,您可以扩展Fixtures命令,并有一个标记,用于对实体进行批处理—前1000行,然后是第二个1000行,等等。

谢谢。我曾尝试在每次插入时刷新,但我认为这是一个太重要的频率。我将尝试您的建议。对不起,SQL日志记录是什么?Doctrine附带了一个日志记录系统,可以保持tr执行SQL查询的ACE。在这种情况下,您不需要它,而且这将是一个无用的内存成本。好的,我理解什么是SQL日志记录。您是对的,这个表来自另一段代码,在这里不是必需的。它工作得很好。在我的linux PC(LAMPP)上完成加载大约需要一分钟.简直难以置信。我正在导入一个包含14列和453000行(200Mo)的CSV。该脚本花了48小时导入所有行。使用此优化,只需10分钟。这太棒了。非常感谢!谢谢。这与Sogara的答案相同。我会尽快尝试。前几天我自己在文档页面上遇到类似问题,我想我会给你一个源,因为我手头有。太好了!看到我的对索加拉回答的评论。