itsimiro / laravel-chunk-cursor
Laravel Eloquent游标,支持预加载和分块
1.0.1
2024-04-02 22:27 UTC
Requires
- php: ^8.1
- laravel/framework: ^10.0|^11.0
Requires (Dev)
- phpunit/phpunit: ^10.0|^11.0
- spatie/ray: ^1.28
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