2011-03-09 28 views
0

我正在使用更新函數,其中我將約40,000行插入到mysql數據庫。在創建該數組時,我出現內存不足錯誤(試圖分配41個字節)。php內存不足,數組闖入子陣列

最終的功能是這樣的:

function Tright($area) { 
    foreach ($area as $a1=>&$a2) { 
     mysql_query('INSERT INTO 0_right SET section=\''.$a2['sec_id'].'\', user_id=\''.$a2['user_id'].'\', rank_id=\''.$a2['rank_id'].'\', menu_id=\''.$a2['menu_id'].'\', droit = 1;'); 
    } 
} 

我有兩個問題。上面的工作負載對於php來說太過自然了嗎?

如果沒有,任何人都可以建議我應該在哪裏檢查?如果是的話,有沒有辦法將$ area數組分割成子數組並執行函數,也許這樣我就不會解決內存不足的問題。任何其他解決方法?

謝謝你們。


編輯:@halfdan,@Patrick Fisher,你們倆都談過要做一個多插入查詢。你如何做到這一點,在這個例子中,請。

+1

您使用的是什麼版本的PHP?循環使用SQL語句通常非常慢,您可能需要多次插入。你給了你的PHP實例多少內存? – halfdan 2011-03-09 23:01:42

+0

您是否在談論這個問題> http://www.electrictoolbox.com/mysql-insert-multiple-records/ – 2011-03-09 23:13:22

+0

我知道這是長時間關閉的,但問題在於foreach($ area爲$ a1 =>&$ a2)&會導致php記住所有$ a2數組。而且您甚至不使用@atrick Fisher的& – winkbrace 2012-11-06 15:51:27

回答

3

首先,您應該將所有值合併到一個INSERT語句中,而不是40,000個不同的查詢。

其次,是的,你的內存不足是很自然的。您可以在運行時增加此限制,例如ini_set(),例如ini_set('memory_limit', '16M');


要一次插入多個值,你的SQL應該是這個樣子:

INSERT INTO 0_right (section, user_id, rank_id, menu_id, droit) VALUES 
(1,1,1,1,1), 
(1,2,1,1,1), 
(1,3,1,1,1) 

你可以建立查詢,像這樣:

$values = ''; 
foreach ($area as $a){ 
    if ($values != ''){ 
     $values .= ','; 
    } 
    $values .= "('{$a['sec_id']}', '{$a['user_id']}', '{$a['rank_id']}', '{$a['menu_id']}', 1)"; 
} 
$sql = "INSERT INTO 0_right (section, user_id, rank_id, menu_id, droit) VALUES $values"; 
+0

:在這個示例中,如何將所有值合併到一個INSERT語句中? – 2011-03-09 23:09:23

+0

@帕特里克費舍爾,在做mysql_query,我得到'有一個大於'max_allowed_pa​​cket'字節的數據包' – 2011-03-09 23:41:02

+0

解決與服務器傢伙。 ;) – 2011-03-10 00:31:06

0

PHP有一個內置(可配置)的內存限制,以防止單個腳本從錯誤的方向陷入整個機器。根據您的版本,該限制默認爲8MB(5.2.0之前),16MB(5.2.0)或128MB(5.3.0)。

您可以通過ini_set或php.ini更改限制。

+0

哇做了默認的設置爲5.3MB O_O爲什麼 – dynamic 2011-03-09 23:04:35

+0

這是5.2.9在我的服務器。 memory_limit:128M。 – 2011-03-09 23:07:02

+0

@ yes123:不知道,可能是因爲他們認爲RAM變得更便宜,應用程序處理更多的數據,並且機器具有大量RAM,因爲它很便宜。就我個人而言,我從來沒有遇到內存限制,但是我的腳本再次處理最多十幾行的工作集,一次不超過40,000行。 – Damon 2011-03-09 23:10:24

1

這些都是很好的解決問題的答案。如果這是一次性腳本,只需修改RAM並確保腳本不會超時(php.ini文件中的max_execution_time),您應該沒問題。

它可能運行得更快,如果它是一個大的插入語句,但那麼你會支付在PHP端構建龐大的查詢的成本(所以內存不足的問題將仍然存在,並會更糟字符串連接)。但老實說,誰在乎你是否僅僅運行一次?但是,如果你要一直執行這個操作(例如在一個網頁上),我會推薦其他方法......比如限制區域大小,剪切特徵或以不同方式存儲數據。

+0

謝謝@Saurav,我將使用它幾次,將一個站點移動到新的位置,進行編碼,調試和測試階段。現在我的新錯誤是'有一個大於'max_allowed_pa​​cket'字節的數據包 – 2011-03-09 23:42:04