关于使用 Lazy Collections 来提高 Laravel Excel 读取的性能详解(轻松支持百万数据)
Laravel  /  管理员 发布于 7年前   131
推荐:laravel教程
我最近的任务是在工作中的一个项目中重构 Excel 导出。 问题是,由于数据集太大,Laravel 无法处理,导出无法再创建。 数据库查询返回了大约 300,000 个结果! 应用程序产生超时或一直内存不足。
一种天真的方法是增加超时时间或内存限制,并希望下次出现问题时,另一个人会处理这个问题。 但这不是我的工作方式。 我不喜欢创可贴。 我喜欢具体的、长期的解决方案。
Laravel Excel 扩展包已经相当灵活。 通过在使用 FromQuery-concerns 时使用「chunks」,它在减少数据库负载方面做得很好。 然而,我们的导出仍然很难处理大数据集。
我和我的同事讨论过,我们是否应该完全重写这个特性:将导出推送到队列中,并在导出结束时向用户发送通知。 然而,这个功能在这个应用程序中只是一个很小的东西。 对我们来说,仅仅为了一个简单的导出而增加如此多的开销是没有意义的。
那天晚些时候,我有一个小小的「我发现了」的时刻,因为我记得 Laravel 中有 LazyCollections 这个东东。
我重新编写了导出:它现在使用 FromCollection-concern,而不是 FromQuery。 我必须对 collection() 方法进行的惟一更改是将查询构建器链末尾的 get() 方法替换为 cursor()。
下面是我们导出功能的简化版本。 Request 对象通过构造函数传递,因此我们可以根据用户在 UI 中选择的内容对查询进行调整。
<?php namespace App\Exports; use App\User; use Maatwebsite\Excel\Concerns\Exportable; use Maatwebsite\Excel\Concerns\FromCollection; use Illuminate\Http\Request; class UsersExport implements FromCollection { use Exportable; protected Request $request; public function __construct(Request $request) { $this->request = $request; } public function collection() { return User::query() ->when($this->request->get('include_subscribed'), function ($q) { return $q->where('is_subscribed', true); }) ->cursor(); // ← 重要的一点 } }
我相信你在你的项目中遇到了内存问题。 你增加了内存限制,希望问题已经解决了 (我自己已经做过无数次了)。
如果是在 Laravel 项目中,我希望,我可以让你重新查看该代码并使用 LazyCollections 重写。
修复这个问题非常有趣,所以我做了一个小小的基准测试:我们的导出现在可以轻松地导出数百万行,而不会遇到内存限制。 太酷了!
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号