2017-07-24 56 views
1

(使用pdo)PHP - 從mysql獲取大型表時發生內存泄露

因此,我有一張表,它的大小几乎爲1 GB,我想從中取出。同時,我正在操作我獲取的數據,然後將其插入到多個其他表中。我的代碼看起來像這樣:

$stmt = $pdo->query("SELECT * FROM foo"); 

$stmt2 = $pdo->prepare("INSERT INTO bar (col1) VALUES (?)"); 
$stmt3 = //...etc 

while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 
    $toInsert = doStuff($row['baz']); 
    $stmt2->execute(array($toInsert)); 

    //etc. 
} 

每當我在完整的表上運行腳本時,它的內存不足。我可以給它更多,但我覺得有更好的方法。

我認爲未緩衝的查詢可能會解決問題,但我需要同時運行這些查詢。

+0

'INSERT INTO bar(col1)(SELECT baz FROM foo)' –

+0

執行批處理,每次少於100條記錄,在出現任何特定行出錯的情況下創建日誌表。 –

回答

1

可以使用未緩衝的查詢讀取併爲插入操作設置另一個PDO連接是一種解決方案嗎?

+0

謝謝,這工作!我已經在這個代碼片段的同一個PDO對象上嘗試了這個想法: '$ statement = $ pdo-> prepare(「SELECT * FROM $ RawPDBData」,array(PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY => false)); $ statement-> execute();' 但這沒有奏效。任何想法爲什麼一個新的PDO對象的作品,但不是這個? –

+0

未緩衝的查詢正在阻止當前(PDO)連接,直到從(MySQL)服務器獲取完整結果集爲止。這就是爲什麼你不能同時重複使用同一個連接,並且你必須爲其他查詢使用第二個連接。 –

+0

爲了澄清,當我說它不起作用時,我的意思是代碼運行但仍然存在內存泄漏。它充當了我已經傳遞給prepare()的額外屬性,甚至不存在。爲什麼這至少爲後續的併發查詢拋出錯誤? –

-1

嘗試用極限分頁和偏移

$limit = 1000; 
$offset = 0; 

$stmt = $pdo->prepare("SELECT * FROM foo ORDER BY id ACC LIMIT :limit OFFSET :offset"); 

$hadResult = false; 
do { 
    $stmt->bindParam(':limit', $pageSize, PDO::PARAM_INT); 
    $stmt->bindParam(':offset', $offset, PDO::PARAM_INT); 

    while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 
     $hadResult = true; 
     ///do stuff 
    } 
    $offset += $limit; 
} while($hadResult); 
1

當你從數據庫中讀取數據,並在PHP中使用它,PHP的對象將內存以及MySQL的(做的工作,給你回的結果)。

您的查詢看起來很簡單。您可以編寫一個包含兩個查詢的語句。這樣它就可以在沒有PHP內存的情況下工作。