【问题标题】:How do I use Laravel's chunk to avoid running out of memory?如何使用 Laravel 的块来避免内存不足?
【发布时间】: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)
    {
        //
    }
});

【问题讨论】:

    标签: php mysql laravel laravel-4 eloquent


    【解决方案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涉及修改可能影响查询的记录,如软删除、硬删除、查询中的列更改等,则需要将块包围一段时间陈述。请参阅stackoverflow.com/questions/32700537/… 和可能的laravel.io/forum/…
    • 我正在运行一些包含 2000 个条目的代码。转换为 json 后,我的对象约为 150 个字节。所以这会生成整洁的 300KByte 块,这对我的数据库、所涉及的数据以及我的 PHP 内存和运行时限制都很有效。
    猜你喜欢
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多