2012-01-10 101 views
0

我正在發佈一個使用CodeIgniter的SQL查詢,它可以返回80,000行以上的結果。每行有三列,所有這些都是整數,我得到一個PHP錯誤: 致命錯誤:允許的內存大小134217728字節用盡大型SQL結果集佔用太多內存 - CodeIgniter

看來,我試圖使用超過128MB來檢索結果MySQL服務器。我正在使用$ query-> result_array()來檢索結果。在我得到的結果中,空間顯然會產生嚴重的開銷。假設我檢索100,000行,有3個整數。所以,10萬*((3 * 4 + 10)= 2.1MB。(10個是用於柱身份證等)。

字節難道我做錯了什麼數?

------ ----------------解決-----------------------

通過修改CodeIgniter代碼解決: link

執行現在更快,腳本只服用內存〜3MB 128MB,而不是向上的。

+4

檢索塊,進程;檢索下一個塊... – 2012-01-10 23:08:23

+0

採取Dagon的建議不要一次採集所有數據。 – 2012-01-10 23:11:43

+0

@Dagon可以向我們展示一些關於如何在大型查詢中完成「檢索塊,進程,檢索下一個塊」的示例? – fujisan 2014-02-21 09:19:43

回答

2

我不知道回報究竟有CI的結果,但你去有限的不希望整個數據集在一個數組中。爲什麼不按需要遍歷每一行?

<?php 

$result = $this->db->query('SELECT ...'); 
while($row = $result->next_row()) 
{ 
    // do something with that single row 
} 
+1

根據我的經驗,這會導致CodeIgniter 2.x將完整的結果集加載到內存中。 – Nate 2015-07-23 22:25:54

1

除非您確實需要檢索所有記錄 - 例如,出口或批量用途 - 我強烈建議總是查詢塊

MySQL's SELECT statement has this option

[LIMIT {[offset,] row_count | row_count OFFSET offset}] 

例如

Limit 10, 200 

提供200條記錄與記錄10開始。

0

即使問題得到解答,3MB仍然很多。你真的需要把它全部存儲在內存中嗎?正常情況下,PHP腳本的運行時間大約在1MB或更少,因爲它在編程時考慮了內存。事實上,你甚至可能達到8MB以上是非常令人不安的,並且在一個真正的生產環境中有成千上萬的頁面點擊,你的服務器會崩潰並燒燬。我強烈建議你修改你的代碼。

+0

這是操作碼和其他緩存的用途。 3MB對於合理複雜的應用程序來說沒有任何意義。而且RAM現在相對便宜。如果您獲得數千頁的點擊量(在3MB有問題的時間範圍內),希望您將您的用戶基礎貨幣化以支付它... – landons 2012-01-11 01:26:55

1

如果您將結果顯示在頁面上,您很可能需要使用分頁。如果您正在對數據執行操作,則需要使用LIMITS和OFFSETS分段執行操作。否則,您將需要增加內存限制,我不建議這個限制大於128MB。

0

我遇到了與CI相同的問題。不幸的是,修改數據庫後端不是我的選擇。所以我的解決辦法是隻使用模型和循環mysqli_功能通過自身的每一條記錄:

$result = mysqli_query($sql); 
while ($row = mysqli_fetch_assoc($result)){ 
    // process batch 
} 

而隨着這樣的記錄工作,我沒有做SQL分頁存儲也沒有全部信息在1陣列上。這也適用於mysql_函數(取決於您使用的數據庫驅動程序)。這裏的缺點:

  • 您沒有使用CI數據庫引擎,所以如果您決定使用不同的驅動程序,則必須手動更新這些查詢。
  • 除非以某種方式存儲數據庫標識符,否則不能使用多個數據庫。

可能還有其他的缺點,但對我來說它的工作原理並不會消耗那麼多的數據。