2014-10-10 4 views
0

PHP 5.5에서 작동하는 스크립트를 얻으려면 실제로 mysql-extension을 PDO로 변경하십시오. mysql-extension을 사용하면 PDO가 잘 작동하지만 PDO를 사용하면 메모리 오버플로가 발생합니다. PDO가 메모리 넘침을 야기 함

protected function getData($table) { 
    global $db; 
    $insert = ''; 
    $stmt = $db->query("-- " . __LINE__ . __FILE__ . " 
    SELECT * 
    FROM " . $table 
); 
    if ($result = $stmt->fetchAll()) { 
    $insert_into = "INSERT INTO `" . $table . "` VALUES ". PHP_EOL; 
    $insert = "/*!40000 ALTER TABLE `" . $table . "` DISABLE KEYS */;" . PHP_EOL; 
    $insert .= $insert_into; 
    $countRow = 0; 
    $split_tmp = ''; 
    foreach ($result as $row) { 
     $insert_tmp = "("; 
     foreach ($row as $data) { 
     if (!isset($data)) { 
      $insert_tmp .= 'NULL,'; 
     } else if ($data != '') { 
      $insert_tmp .= "'" . addslashes($data) . "',"; 
     } else { 
      $insert_tmp .= "'',"; 
     } 
     } 
     $insert_tmp = rtrim($insert_tmp, ',') . '),' . PHP_EOL; 
     $insert .= $insert_tmp; 
     if ($this->querySplit) { 
     $split_tmp .= $insert_tmp; 
     if ($countRow > $this->maxRow && strlen($split_tmp) > $this->maxLength) { 
      $countRow  = 0; 
      $split_tmp = ''; 
      $insert = rtrim($insert, PHP_EOL . ',') . ';' . PHP_EOL; 
      $insert .= "/*!40000 ALTER TABLE `" . $table . "` ENABLE KEYS */;" . PHP_EOL . PHP_EOL; 
      $insert .= "/*!40000 ALTER TABLE `" . $table . "` DISABLE KEYS */;" . PHP_EOL; 
      $insert .= $insert_into; 
     } 
     } 
     $countRow ++; 
    } 
    $insert = rtrim($insert, PHP_EOL . ',') . ';' . PHP_EOL; 
    $insert .= "/*!40000 ALTER TABLE `" . $table . "` ENABLE KEYS */;" . PHP_EOL. PHP_EOL; 
    } 
    return $insert; 
} 

심지어 도움이되지 않습니다

$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); 

로 변경 : 여기

은 내가 사용하는 기능입니다.

memory_limit는 256MB로 설정됩니다. 많은 양의 데이터를 처리 할 때

+2

PDO를 사용하여 다음 조정을 수행 fetchAll()의 사용은 메모리 오버 플로우가 발생, 매우 나쁜 생각을 fetchAll이다 사용 . 한 번에 하나의 행을 가져옵니다. –

+1

'fetchAll()'을 호출하면 전체 결과 세트가 메모리에 버퍼링됩니다. 트릭은 가능한 한 쿼리 결과를 줄이면 (특히 테이블에 많은 수의 열이있는 경우) SELECT * 대신 SELECT SELECT1, field2를 사용하여 MySQL이 가능한 한 작업을 수행하도록하는 것입니다. 50000 개의 행을 가져 오면 ... 여기에 문제가 있는지 확인할 수 있습니다. 또한 PHP_EOL을 짧은 함수로 12 번 호출하는 이유는 무엇입니까? 명령 줄을 통해 전화를 걸거나 내보내는 중입니까? – iamgory

+0

스크립트가 전체 데이터베이스를 백업하기 때문에 모든 테이블 필드가 필요합니다. 따라서 필드의 이름을 지정하면 솔루션이 변경되지 않습니다. –

답변

0

메모리 오버 플로우가 발생하지 않습니다 fetch()

protected function getData($table) { 
    global $db; 
    $insert = ''; 
    $stmt = $db->query("-- " . __LINE__ . __FILE__ . " 
    SELECT * 
    FROM " . $table 
); 
    if ($result = $stmt->rowCount() > 0) { 
    $insert_into = "INSERT INTO `" . $table . "` VALUES ". PHP_EOL; 
    $insert = "/*!40000 ALTER TABLE `" . $table . "` DISABLE KEYS */;" . PHP_EOL; 
    $insert .= $insert_into; 
    $countRow = 0; 
    $split_tmp = ''; 
    while($row = $stmt->fetch()) { 
     $insert_tmp = "("; 
     foreach ($row as $data) { 
     if (!isset($data)) { 
      $insert_tmp .= 'NULL,'; 
     } else if ($data != '') { 
      $insert_tmp .= "'" . addslashes($data) . "',"; 
     } else { 
      $insert_tmp .= "'',"; 
     } 
     } 
     $insert_tmp = rtrim($insert_tmp, ',') . '),' . PHP_EOL; 
     $insert .= $insert_tmp; 
     if ($this->querySplit) { 
     $split_tmp .= $insert_tmp; 
     if ($countRow > $this->maxRow && strlen($split_tmp) > $this->maxLength) { 
      $countRow  = 0; 
      $split_tmp = ''; 
      $insert = rtrim($insert, PHP_EOL . ',') . ';' . PHP_EOL; 
      $insert .= "/*!40000 ALTER TABLE `" . $table . "` ENABLE KEYS */;" . PHP_EOL . PHP_EOL; 
      $insert .= "/*!40000 ALTER TABLE `" . $table . "` DISABLE KEYS */;" . PHP_EOL; 
      $insert .= $insert_into; 
     } 
     } 
     $countRow ++; 
    } 
    $insert = rtrim($insert, PHP_EOL . ',') . ';' . PHP_EOL; 
    $insert .= "/*!40000 ALTER TABLE `" . $table . "` ENABLE KEYS */;" . PHP_EOL. PHP_EOL; 
    } 
    return $insert; 
} 
관련 문제