如何使用 Laravel 的块来避免内存不足?

Posted

技术标签:

【中文标题】如何使用 Laravel 的块来避免内存不足?【英文标题】:How do I use Laravel's chunk to avoid running out of memory? 【发布时间】:2015-03-20 20:40:31 【问题描述】:

我从临时表中提取大约 10 万条记录,对数据进行一些细微修改,下载照片,然后将我需要保留的字段放入“主”表中。这很快导致我的应用程序因内存不足而崩溃。

我阅读了关于在 Laravel 雄辩的 ORM 中使用 chunk() 的非常简短的文档,但我什至不知道如何开始在我的课堂上实现它。

这是我目前正在做的事情:

    public function fire()

    // Turn off query logging
    DB::connection()->disableQueryLog();

    $feeds = RetsFeed::where('active','=',1)->get();
    foreach ($feeds as $feed)
    

        $class = "TempListing$feed->board";

        $listings = $class::orderBy('MatrixModifiedDT','desc')->get();

        $listings->each(function($listing) use ($feed) 
            ListingMigrator::migrateListing($listing,$feed);
            echo "Feed: $feed->board\r\n";
            echo "SubcondoName: $listing->SubCondoName\r\n";
            echo "Development: $listing->Development\r\n";
            echo "\r\n";
        );
    


每个提要(或数据源)都被转储到临时表中的不同杂务中。这很好用。然后,我从一张表(平均大约 30k)中获取所有 hte 列表并运行我的 ListingMigrator 方法。

在这个例子中我应该把块放在哪里?它会取代这一行吗:

$listings = $class::orderBy('MatrixModifiedDT','desc')->get();

我不完全理解雄辩文档中的闭包。这就是他们要说的全部内容,这是来自 Laravel 网站的代码示例:

    User::chunk(200, function($users)

    foreach ($users as $user)
    
        //
    
);

【问题讨论】:

【参考方案1】:

chunk 调用应替换 get 调用 - 它旨在处理 pre-get() 查询构建器对象。

$listings = $class::orderBy('MatrixModifiedDT','desc');

$listings->chunk(200, function($listings) use($feed) 
    $listings->each(function($listing) use ($feed) 
        ListingMigrator::migrateListing($listing,$feed);
        echo "Feed: $feed->board\r\n";
        echo "SubcondoName: $listing->SubCondoName\r\n";
        echo "Development: $listing->Development\r\n";
        echo "\r\n";
    );
);

【讨论】:

这似乎很有魅力!非常感谢您的慷慨回答。不过,我的一个问题是我们如何确定该块的 200 号。我的理解是,它处理了那么多,然后基本上“重新开始”,因为没有更好的词。将这个数字保持在非常低的水平,甚至是 10,难道不是安全的吗?这样做的唯一成本是额外的数据库调用吗? @ChrisFarrugia 块大小是相当随意的,唯一的硬要求是它是一个足够小的数字,因此您不会在单个块中用完 RAM。如果您的数据库不介意负载,那么 10 个块就可以了。 200 块也可以。 注意:如果chunk涉及修改可能影响查询的记录,如软删除、硬删除、查询中的列更改等,则需要将块包围一段时间陈述。请参阅***.com/questions/32700537/… 和可能的laravel.io/forum/… 我正在运行一些包含 2000 个条目的代码。转换为 json 后,我的对象约为 150 个字节。所以这会生成整洁的 300KByte 块,这对我的数据库、所涉及的数据以及我的 php 内存和运行时限制都很有效。

以上是关于如何使用 Laravel 的块来避免内存不足?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免由于内存不足导致的gcc崩溃

当我运行命令计划laravel时,如何解决“致命错误:内存不足...”?

如何避免由于太多ajax调用而导致浏览器内存不足错误

Laravel CSV 导入内存不足(允许内存耗尽)

laravel composer update 内存不足

如何避免内部类中的内存泄漏