2013-04-18 100 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時,你會像嬰兒一樣哭泣。