PHP内存不足

dev02

我试图将数据从postgres数据库插入mysql数据库。关于100000我需要导入的记录。但是Iam总是会出现内存不足的问题。

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函数或地图函数内部的循环出了问题。我什至尝试将内存设置和时间限制设置为无限制,但无济于事。可能是我需要使用参考变量或其他内容,但是我不确定如何使用。

可以在上述代码中进行任何优化以减少内存使用吗?

或者如何通过代码将大型数据库中的大数据有效地导入MySQL?

谁能告诉我我在这里做错了,还是为什么整个内存都被消耗了?

PS:我正在具有4GB内存(Windows 8)的本地开发计算机上执行此操作。PHP版本:5.6.16

罗斯兰·奥斯曼诺夫(Ruslan Osmanov)

肯定地,您在某处内存泄漏。我猜想中的某处$chunk->map(),或$object->insert($fixedChunk->toArray())我们只能猜测,因为实现是隐藏的。

但是,我将尽可能使用生成器该代码可能类似于以下内容:

function getAllItems() {
  $step = 2000;

  for ($offset = 0 ;; $offset += $step) {
    $q = "SELECT * FROM items_table LIMIT $offset, $step";

    if (! $items = Db::fetchAll($q)) {
      break;
    }

    foreach ($items as $i) {
      yield $i;
    }
  }
}

foreach (getAllItems() as $item) {
  import_item($item);
}

我敢说,使用生成器,您几乎可以将任何数量的数据从一个数据库导入到另一个数据库。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章