2013-04-18 63 views
1

我仍然遇到Cake的Mempry使用问题。我读了很多威胁,并尝试了1000件事情,但没有什么帮助。 我使用CakePHP 2.4.x.使用MySQLdB。我编写了一个API来从数据库中选择日志数据。我做了一个测试来解释我多么困惑。我有一个选择返回与11列1400行。我的一般内存使用(使用memory_get_usage)大约是4MB。 后,我选择具有:CakePHP的内存分配问题

$condition = array('conditions'=> array(


    'LogBackend.created_at between ? AND ?' => array(
              $this->params['url']['from'],$this->params['url']['to'] 
             ))); 

    $this->data = $this->LogBackend->find('all', $condition). 

我的内存使用量只是爆炸比9MB以上。数据依然没有任何回报或任何工作。只是选择。那么9MB并没有那么多,但如果我选择更多,就应该有可能围绕100k行左右。我的256MB空间不足。 有人可以告诉我这种荒谬的内存使用的原因?

问候

+0

您是否在使用可容忍的行为?你是否在某处设置了'$ recursive'? – Nunser

+0

你真的需要在内存中有100k行吗?你不能限制你的查询使用有限的一组数据吗?或者使用循环选择,处理和清理数据?这不是一个CakePHP内存问题,它是一个方法问题。 – cernunnos

+1

@cernunnos我同意,当然取决于具体目的,这可以以不同的方式实现。但是,国际海事组织在这里不是没有责任。 CakePHP模型总是以数组的形式返回结果,导致整个记录集被加载到内存中。例如,如果OP想要实现导出功能,那么通过标准的CakePHP模型是不可能的。创建使用[无缓冲查询]的自定义模型/数据源(http://php.net/manual/en/mysqlinfo.concepts.buffering.php)可能是一个解决方案。 – thaJeztah

回答

0

只需使用PAGINATE代替,并在块处理您的数据。蛋糕面向大约20行左右的视图。但是我们经常想要生成基于数百万行的报表。 CakePhp有一个名为paginate的函数,可以很有效地欺骗mysql LIMIT 100000,1000。我发现这些黑客通过Google的搜索非常激烈,Cakephp 1.3有一些稍微不同的语法,如果没有人发布有关Cake 3的信息,并且它发生了变化,我可能会在某天回来发布信息。

// cakephp 2.4.1 
$condition = array('conditions'=> 
array('LogBackend.created_at between ? AND ?' => 
array($this->params['url']['from'],$this->params['url']['to']))); 

$this->paginate['conditions'] = $conditions['conditions']; 
$this->paginate['limit'] = 1000; 
// could also use ['fields'] = array('filed1', 'field2'); to limit memory 

/******* here is where we trick paginate to iter in the ctrlr *****/ 
$this->request->params['named']['page']=1; 
$this->request->params['paging']['ModelName']['nextPage'] = true; 
// get chunks 
while ($this->request->params['paging']['ModelName']['nextPage']) { 
    $Rows = $this->paginate("ModelName"); 
    // boil down this chunk of data 
    $this->request->params['named']['page']+=1; 
} 

将数百万行传回视图是没有意义的。 while循环将每次覆盖$ Rows,重新使用该核心内存。因此,挑战在于找到一种巧妙的方法来提炼数据,或者在循环过程中编写一个新表格,以便在下一次提炼时使用。由于模型处理开销,Cakephp的执行速度仍然较慢,所以如果有很多不需要的列,可以使用paginate ['fields']来只处理你需要的字段。字段与列相同。

PHP在哲学上与Apache并存,所以它确实不适用于这类事情。它意味着在30秒或更短的时间内获得结果并呈现网页。这不仅仅是蛋糕的责任。 Python和Ruby可能会更好,甚至Perl。但是当你必须筛选工具来格式化html时,你会像婴儿一样哭泣。