0
Чтобы получить скрипт, работающий с PHP 5.5, я фактически перехожу от mysql-расширения к PDO. С mysql-расширением он отлично работает, но с 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 устанавливается равным 256 МБ.
PDO не вызывает переполнение памяти, ваше использование fetchAll() вызывает переполнение памяти , Выбирайте свои строки по одному за раз –
Весь ваш набор результатов буферизуется в память, когда вы вызываете 'fetchAll()'. Хитрость заключается в том, чтобы позволить MySQL выполнять работу там, где это возможно, уменьшая набор результатов с помощью вашего запроса - то есть 'SELECT field1, field2' вместо' SELECT * ', особенно если таблица имеет большое количество столбцов. Если вы опускаете 50000 строк ... ну, вы можете увидеть эту проблему здесь, конечно? Кроме того, почему вы вызываете PHP_EOL 12 раз за одну короткую функцию? Вы вызываете это через командную строку или экспортируете ее? – iamgory
Мне нужны все поля таблицы, потому что скрипт должен архивировать всю базу данных. Поэтому ваше решение с именованием полей ничего не изменит. –