Php PDO导致内存溢出

Php PDO导致内存溢出,php,mysql,pdo,Php,Mysql,Pdo,为了让脚本使用PHP5.5,我实际上将mysql扩展更改为PDO。mysql扩展可以正常工作,但PDO会导致内存溢出 以下是我使用的函数: protected function getData($table) { global $db; $insert = ''; $stmt = $db->query("-- " . __LINE__ . __FILE__ . " SELECT * FROM " . $table ); if ($result

为了让脚本使用PHP5.5,我实际上将mysql扩展更改为PDO。mysql扩展可以正常工作,但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);
没用


内存限制设置为256MB。

使用
fetchAll
处理大量数据时是一个非常糟糕的主意,请使用
fetch()执行以下调整。


PDO不会导致内存溢出,使用fetchAll()会导致内存溢出。每次提取一行调用
fetchAll()
时,整个结果集将被缓冲到内存中。诀窍是让MySQL尽可能通过使用查询缩小结果集来完成工作,即
selectfield1,field2
而不是
SELECT*
,尤其是当表有大量列时。如果你把50000排排下来…你肯定能看到这里的问题?另外,为什么要在一个短函数中调用PHP_EOL 12次?您是通过命令行调用它还是导出它?我需要所有的表字段,因为脚本要备份整个数据库。因此,命名字段的解决方案不会改变任何东西。
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;
}