关于一个 Laravel 使用 cursor 占用内存问题

本文探讨了在 Laravel 中使用 Eloquent 的 cursor 方法处理大量数据时遇到的内存占用问题。作者发现,当 PDO::ATTR_EMULATE_PREPARES 设置为 false 时,内存使用量会随着数据行的遍历逐渐增加,而设置为 true 时内存使用保持稳定。寻求对这一现象有深入了解的大神解答。
摘要由CSDN通过智能技术生成

背景
我需要把一张表的所有数据查询出来,然后逐一查询出来进行逻辑处理。
代码如下:

public function handle()
{
    EloquentStoredEvent::query()->cursor()->each(function (EloquentStoredEvent $storedEvent){
        // 逻辑处理
        $this->info(round(memory_get_usage()/1024/1024, 2).'MB');
    });
}

在代码中,我使用了 Eloquent 的 cursor, 他的原理就是使用了 PDO 的 execute 方法,将数据库的结果集放到 php 的内存中,然后通过 php 的生成器 一行一行从结果集 fetch 出来数据转换成 orm 对象。这个比起使用 Eloquent 的 get 更能节约内存开销。

问题
当我执行代码的时候。它会一行行执行

$this->info(round(memory_get_usage()/1024/1024, 2).'MB');

我发现了个问题,假如有 80 万条数据,第一次执行内存占用 962.36MB,后面会慢慢增加,到最后一次执行内存占用 1901.39MB。
那如果有一个脚本需要长时间才能处理完成,你开始观察几分钟可能正常,但是看你过了半个小时它就因为内存不够而运行失败。

找到原因
后面我发现和 PDO::ATTR_EMULATE_PREPARES 有关系,在 Illuminate\Database\Connectors\Connector 默认 PDO::ATTR_EMULATE

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值