1

我仍然对 Cake 的内存使用有疑问。我阅读了很多威胁并尝试了 1000 种东西,但没有任何帮助。我使用 CakePHP 2.4.x。使用 MySQLdB。我编写了一个 API 来从数据库中选择日志数据。我做了一个测试来解释是什么让我如此困惑。我有一个选择,它返回 11 列的 1400 行。我的一般内存使用量(使用 memory_get_usage)约为 4MB。在我选择之后:

$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 空间用完了。谁能告诉我这种荒谬的内存使用的原因?

此致

4

1 回答 1

0

只需使用 paginate 代替,并以块的形式处理您的数据。Cake 是面向 20 行左右的大块的视图。但通常我们希望生成基于数百万行的报告。CakePhp 有一个名为 paginate 的函数,它可以被欺骗以非常有效地执行 mysql LIMIT 100000,1000。我通过非常激烈的谷歌搜索发现了这些黑客,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 时,您会像婴儿一样哭泣。

于 2015-08-05T23:19:48.343 回答