【发布时间】:2016-04-22 06:40:52
【问题描述】:
我正在尝试将 postgres 数据库中的数据插入 mysql 数据库。我需要导入大约 100000 记录。但是,我总是出现内存不足的问题。
Out of memory (allocated 1705508864) (tried to allocate 222764 bytes)
我正在使用 Laravel 5 来执行此操作,代码如下:
// to avoid memory limit or time out issue
ini_set('memory_limit', '-1');
ini_set('max_input_time', '-1');
ini_set('max_execution_time', '0');
set_time_limit(0);
// this speeds up things a bit
DB::disableQueryLog();
$importableModels = [
// array of table names
];
$failedChunks = 0;
foreach ($importableModels as $postGresModel => $mysqlModel) {
$total = $postGresModel::count();
$chunkSize = getChunkSize($total);
// customize chunk size in case of certain tables to avoid too many place holders error
if ($postGresModel === 'ApplicationFormsPostgres') {
$chunkSize = 300;
}
$class = 'App\\Models\\' . $mysqlModel;
$object = new $class;
// trucate prev data //
Eloquent::unguard();
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
$object->truncate();
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
Eloquent::reguard();
$postGresModel::chunk($chunkSize, function ($chunk) use ($postGresModel, $mysqlModel, $failedChunks, $object) {
// make any adjustments
$fixedChunk = $chunk->map(function ($item, $key) use ($postGresModel) {
$appendableAttributes = $postGresModel::APPEND_FIELDS;
$attributes = $item->getAttributes();
// replace null/no values with empty string
foreach ($attributes as $key => $attribute) {
if ($attribute === null) {
$attributes[$key] = '';
}
}
// add customized attributes and values
foreach ($appendableAttributes as $appendField) {
if ($appendField === 'ssn') {
$value = $attributes['number'];
$attributes[$appendField] = substr($value, 0, 4);
} else {
$attributes[$appendField] = '';
}
}
return $attributes;
});
// insert chunk of data in db now
if (!$object->insert($fixedChunk->toArray())) {
$failedChunks++;
}
});
}
当大约80000 行不是在此之前插入时,就会出现内存问题。
我怀疑集合 map 函数或 map 函数内的循环有问题。我什至尝试将内存设置和时间限制设置设置为无限制,但无济于事。可能是我需要使用引用变量或其他东西,但我不确定如何。
可以对以上代码进行优化以减少内存使用吗?
或者如何通过代码高效地将大型PostgreSQL数据库中的大数据导入MySQL?
谁能告诉我在这里做错了什么或者为什么整个内存都被消耗掉了?
PS:我在具有 4GB 内存(Windows 8)的本地开发机器上执行此操作。 PHP版本:5.6.16
【问题讨论】:
-
您允许 PHP 使用多少内存? (这可以在
php.ini中更改)。对不起,忽略这个:p 我没有看到你的代码的开头。 -
@PXgamer:在第一行可以看到无限
ini_set('memory_limit', '-1');我还尝试设置为其他值,例如ini_set('memory_limit', '1024MB');或更大,但没有运气。 -
你试过减小块大小吗?
-
@Sarcoma:是的,尝试将 at 设置为较小的值,但奇怪的是,它在大约
80000记录时再次出现内存不足 -
有什么“32 位”应用程序吗? 1.7G 是此类应用无法胜任的地方。
标签: php mysql laravel memory-management