教义和大量数据

问题描述 投票:0回答:3

我有一个返回约 50k 行的查询, 似乎学说将整个结果放入内存中超出了内存限制(128M) 我发现节省一些内存的唯一解决方案是

$result->execute(array(), Doctrine_Core::HYDRATE_NONE);

但还是超出了限制, 有没有办法用教义一次读一行?

php doctrine
3个回答
6
投票

更新: 以下链接现已失效,当前文档位于here

学说文档 - 13.批处理(已死)

更新: 对于 1.2,请查看此页面: http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/data-Hydrators.html(已死)

在“按需”标题下您将找到答案。


1
投票

批处理有帮助!

我花了很长时间才弄清楚什么有帮助。我的印象是,只要你停留在同一个 php 进程中,你就无法释放你的内存。所以这对我来说没有帮助

  • $object->free(true)
  • 取消设置($对象)
  • sfConfig::set('sf_debug', false)
  • gc_collect_cycles() / gc_enable()
  • Doctrine_Core::HYDRATE_ON_DEMAND
  • sfCommandApplicationTask::runTask()
  • sfDoctrinePager

真正有帮助的是来自 Rich Sage 的提示,他建议生成子进程来执行部分工作。查询的限制和偏移量作为进程之间的参数给出。要逐行获取,请将 $options['limit']

 设置为 1,但 50 也应该是一个不错的值:

daddyTask.class.php

[..] $total = ItemTable::getInstance()->createQuery('i')->count(); for ($offset = 0; $offset < $total; $offset += $options['limit'] ) { passthru( sprintf('%s %s/symfony doTask --limit=%s --offset=%s', sfToolkit::getPhpCli(), sfConfig::get('sf_root_dir'), $options["limit"], $offset), $returnVar ); }

doTask.class.php

$items = ItemTable::getInstance()->createQuery('i')->limit($options['limit'])->offset($options['offset'])->execute(); foreach( $items as $item ) { // ..do something with the item $this->log( 'INFO: '.memory_get_peak_usage(true).' memory in use.' ); }

(我在 PHP 5.3.10 上的 Symfony 1.4 框架中使用 Doctrine 1.2)

非常感谢有关此主题的任何评论或批评,因为这对我来说是一个困难!


0
投票
你不使用 ->limit() 和 ->offset() 有什么原因吗?

© www.soinside.com 2019 - 2024. All rights reserved.