关于导出重组数据,有什么更快的方法吗

比如订单表,有个 user_id,需要导出有十万条数据。比如导出的字段有个用户名称字段。就需要关联去 user 表拿到 name。然后循环重组数据。等于再次循环十万次。下面代码示例:

$orders = Order::with('user')->get();
//导出数据
$export_data = [];
foreach($orders as $order){
    $export_data = [
        'no' => $order->no,
        //必须循环重组这个user_name字段
        'user_name' => $order->user->name,
    ];
}

//导出
Export($export_data);

请问有什么好方法,可以不用循环重组数据吗,直接查出来就可以塞进导出所需要的数据里

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 22

你直接 leftjoin 不行吗 我没看错的话你只是把关联的用户名拿到外边把
DB::table(‘orders’) ->leftJoin(‘users’, ‘orders.user_id’, ‘=’, ‘users.id’) ->get();

1年前 评论
忆往昔弹指间 1年前
svaa (楼主) 1年前
Rache1 1年前
怎样的心 (作者) 1年前

对于大量数据的查询最好是分页查,而不是一次性捞几万几十万数据

$paginator = Order::paginate($page,1000);
$orders  =  $paginator->items;
$userIds = $orders->pluk('user_id');
$users = User::whereIn('id',$userIds->toArray());
$usersMap = array_column($users->toArray(),null,'id');

foreach($orders as $order){
    $export_data = [
        'no' => $order->no,
        'user_name' => $usersMap[$order->user_id]['name'] ?? '',
    ];
}
1年前 评论
svaa (楼主) 1年前
随波逐流
1年前 评论
svaa (楼主) 1年前
随波逐流 (作者) 1年前
Adachi 1年前
Adachi 1年前
周小云 1年前

2 种方案,一种分批次导入(类似 2 楼,不过写的不是很对,思路就是这个思路,节省内存),一种一次性导入(此方案参考 1 楼使用 join 连表)。

1年前 评论

这两天导出数据挺火的呀 :speak_no_evil:

1年前 评论
clyde-cn

分两步 1、加索引呀 2、需要哪个查哪个 导出或许可以试试 xlswriter

1年前 评论
jiangjun

放异步任务里面,慢一点有什么关系吗, 另外数据量大,不建议连表查,单表查询,再组装。

1年前 评论
test2018

xlswriter

1年前 评论

也有可能是因为一次性导出太多 Excel 表字段的问题,建议用 join 链接,对于数据量少的关联表直接先全部取出来在循环里面用数组下标的方式匹配拼接,放队列导出

1年前 评论
ShiKi

chunkById 导出 csv 上百万数据也是随便导出

1年前 评论
sanders

没看懂,你这里的 $export_data 明显是最后一条数据。

你用了 with 方法,一般会用默认用 in 条件查询关联数据。

你这里若是几十万的数据,一次查出一般情况是出不来的,你需要使用 chunkById 方法分批进行查询导出。

上万行的数据缓冲在内存里开销也很大,一般使用 csv 文件追加写入处理交好。

1年前 评论
DogLoML

这种一般是查询慢导致的,不是组装数据的问题,建议用 xlswriter 分块导出,一次全查出来的话内存占用特别大,还可以丢队列里面慢慢跑,前端轮询显示个导出进度就行了。

1年前 评论