itsimiro/laravel-chunk-cursor

Laravel Eloquent游标,支持预加载和分块

1.0.1 2024-04-02 22:27 UTC

This package is auto-updated.

Last update: 2024-09-08 13:12:44 UTC


README

此包提供了一种功能,为Illuminate\Database\Eloquent\Builder类添加了chunkCursor。这使得您可以使用游标分块获取大数据集,从而减少内存使用并使用预加载!

为什么要使用这个?

游标构建器的eloquent方法不支持预加载关系,但使用此包,您将能够像以前一样使用with()load(),并享有cursor()的所有魅力。

安装

您可以通过composer安装此包

composer require itsimiro/laravel-chunk-cursor

用法

以下是一个如何使用chunkCursor宏的示例

使用cursor()

use App\Models\User;

User::query()->with(['articles', 'friends'])->cursor()->each(function (User $users) {
    // Process user... But 'articles' and 'friend' won't be loaded here :(
});

使用chunkCursor()

use App\Models\User;

User::query()->with(['articles', 'friends'])->chunkCursor(50)->each(function (Collection $users) {
    foreach ($users as $user) {
        // Process user... With eager loading! :)
    }
});

在这个例子中,用户以50个一组的方式被获取。您可以根据需要调整块大小。

比较执行时间

让我们在不使用预加载的情况下进行对比,我们将看到chunkCursor的速度快了两倍。

使用cursor()

$startCursor = microtime(true);

DatabaseChunkCursorTestUser::query()->cursor()->each(function (DatabaseChunkCursorTestUser $user) use (&$i) {
    $this->assertEquals(true, true);
});

$endCursor = microtime(true);

$timeCursor = number_format($endCursor - $startCursor, 6); // 0.006624

使用chunkCursor()

$startChunkCursor = microtime(true);

// 1000 rows
DatabaseChunkCursorTestUser::query()->chunkCursor(10)->each(function (Collection $users) use (&$i) {
    $i += 10;
    $this->assertLessThanOrEqual(10, $users->count());
});

$endChunkCursor = microtime(true);

$timeChunkCursor = number_format($endChunkCursor - $startChunkCursor, 6); // 0.003406

正如您所看到的,如果我们添加关系加载,游标将工作得更慢,因为它将不得不每次都向数据库发出新的请求以获取数据。

测试

要为此包运行测试,请使用以下命令

composer test