【问题标题】:Faster persist and flush for doctrine mongodb odm import为学说 mongodb odm 导入更快的持久化和刷新
【发布时间】:2013-07-03 21:47:01
【问题描述】:

我正在使用 symfony2 和学说 mongodb odm 从 CSV 文件导入产品数据。我创建了一个控制台命令来创建Product 对象,然后将它们持久化并刷新DocumentManager。冲洗需要 30 秒以上,而我只有几千种产品。未来可能会有更多。

我想知道是否有任何优化/最佳实践可以在原则上更快地刷新大量新对象。似乎不需要对对象进行太多处理,因为它们都是新的,只需要添加到集合中即可。

【问题讨论】:

  • 您是一次性冲洗这 几千 个产品还是在每次坚持后冲洗?
  • 你确定问题是flush操作,而不是之前的处理?你对它进行了基准测试吗?
  • 我做到了,CSV 的解析、对象的创建和持久化都需要 1-2 秒。最后的刷新调用需要 30 多秒。
  • 也许您可以启用 Doctrine 的日志记录和分析。一定要对 MongoDB 做同样的事情。我认为问题不在于 PHP 处理...
  • 对不起,我是个白痴。开启了 xdebug 分析器。仍然需要 7 秒才能将其关闭,但我想这更合理?

标签: symfony doctrine-odm import-from-csv


【解决方案1】:

我遇到了类似的问题(从 csv 加载数千种产品)。我的问题更多地围绕着内存不足,但解决方案也显示出速度的显着提高。

基本上,我在循环中放置了一个计数器并刷新了管理器,然后每隔一段时间就清除它。我发现 150 批大小产生了最好的结果。我确信这在很大程度上取决于您如何处理它,因为我在插入数据之前进行了大量的数字运算以清理数据。

作为参考,它加载了大约 5,500 个具有 100 多个字段的产品,并在大约 20 秒内对其进行处理。修改之前需要 3 多分钟(如果由于内存不足而完全完成的话。)

//LOOP  {
   if ($count % $batchSize == 0) {
      $manager->flush();
      $manager->clear();
      gc_collect_cycles();
      if ($count % $batchSize == 0)
         echo $count . ' | ' . number_format((memory_get_usage() / 1024), 4) . " KBs\n";
   }
$count++;
}

不要忘记在循环完成后至少再运行一次 $manager->flush() 以捕获那些不会在循环中触发它的 1-149 条记录。

【讨论】:

  • +1 表示循环后刷新的最终提示。我浪费了 2 个小时试图修复一个没有得到更新结果的测试,因为 ;)
【解决方案2】:

我有一个非常大的数据库。我发现每次插入代码时进行刷新会更有效,可以更好地管理对数据库的访问。

$dm->persist($object);
$dm->flush();
$dm->clear();

【讨论】:

  • 这样做可能会导致开销增加并使速度问题变得更糟,因为需要在每条记录之后运行完整的 UOW 计算。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多