小编dmo*_*ors的帖子

使用Laravel在MySQL中导入大型CSV文件

我有一个csv文件,范围从50k到超过100k行数据.

我目前正在使用Laravel w/Laravel Forge,MySQL和Maatwebsite Laravel Excel软件包.

这是由最终用户而不是我自己使用,所以我在我的刀片视图上创建了一个简单的表单:

{!! Form::open(
    array(
        'route' => 'import.store', 
        'class' => 'form',
        'id' => 'upload',
        'novalidate' => 'novalidate', 
        'files' => true)) !!}

    <div class="form-group">
        <h3>CSV Product Import</h3>
        {!! Form::file('upload_file', null, array('class' => 'file')) !!}
    </div>

    <div class="form-group">
        {!! Form::submit('Upload Products', array('class' => 'btn btn-success')) !!}
    </div>
{!! Form::close() !!}
Run Code Online (Sandbox Code Playgroud)

然后,这将成功地将文件存储在服务器上,现在我可以使用诸如foreach循环之类的东西来迭代结果.

现在这里是我按时间顺序和修复/尝试面临的问题:(10k行测试csv文件)

  1. [问题] PHP超时.
  2. [remedy]将其更改为通过作业命令异步运行.
  3. [result]最多可输入1500行.
  4. [问题]服务器内存不足.
  5. [补救措施]添加了1GB的交换驱动器.
  6. [结果]最多可输入3000行.
  7. [问题]服务器内存不足.
  8. [补救]打开每块250行的分块结果.
  9. [result]最多可输入5000行.
  10. [问题]服务器内存不足.
  11. [补救]删除了一些转置/连接表逻辑.
  12. [result]最多可输入7000行.

正如你所看到的结果是边缘的,远不及50k,我甚至几乎不能接近10k.

我已经阅读并研究了可能的建议,例如:

  • 使用原始查询运行"加载数据本地Infile".
  • 导入前拆分文件.
  • 存储在服务器上然后将服务器拆分成文件并让cron处理它们.
  • 作为最后的手段,将我的512mb DO液滴升级到1gb.

使用加载数据本地infile可能无法工作,因为我的标题列可能会更改每个文件,这就是为什么我有逻辑来处理/迭代它们.

在导入之前拆分文件在10k以下是好的但是对于50k或更多?那将是非常不切实际的.

存储在服务器上然后让服务器拆分并单独运行它们而不会给最终用户带来麻烦?可能但甚至不确定如何在PHP中实现这一点,但只是简单地了解一下.

还要注意,我的队列工作程序设置为10000秒超时,这也是非常不切实际和糟糕的做法,但似乎这是它在内存受到打击之前继续运行的唯一方式.

现在我可以放弃并将内存升级到1gb,但我觉得它最好可能会在重新失败之前将我跳到20k行.有些东西需要快速有效地处理所有这些行. …

php mysql csv laravel laravel-5.1

4
推荐指数
1
解决办法
6059
查看次数

标签 统计

csv ×1

laravel ×1

laravel-5.1 ×1

mysql ×1

php ×1