ホームページ  >  記事  >  バックエンド開発  >  Laravel クエリの最適化: データをチャンクする正しい方法

Laravel クエリの最適化: データをチャンクする正しい方法

王林
王林オリジナル
2024-09-09 06:31:38788ブラウズ

Optimizing Laravel Queries: The Right Way to Chunk Data

チャンクの使用を避けるべき理由は何ですか?

バッチ更新中の行の欠落を避けるために、chunk の代わりに chunkById を使用することをお勧めします。チャンクを使用すると、行の更新後に後続のクエリのオフセットがシフトされ、未処理の行がスキップされる可能性があります。

例:

Post::where('processed', 0)->chunk(100, function($posts) {
    foreach($posts as $post) {
       $post->processed = 1;
       $post->save();
    }
});

上記のコードは次のクエリを生成します。

select * from `posts` where `processed` = 0 limit 100 offset 0
select * from `posts` where `processed` = 0 limit 100 offset 100
...

最初のチャンクは 100 行を更新します。 2 番目のクエリは、これを認識せず、オフセットを引き続き使用するため、未処理の 100 行をスキップします。

上記については
で詳しく説明されています タイ・グエン・フン

限られた数の行をチャンクする方法は?

Laravel の chunk() メソッドを使用して限られた数の行を処理しようとすると、次のコードは 2 つのバッチで 5 ユーザーのみを処理すると予想される場合があります。

$query  = \App\Models\User::query()->take(5);

$query->chunk(2, function ($users) {
  // Process users
});

ただし、これはデータベース内のすべてのユーザーを一度に 2 人ずつ処理します。これは、Laravel の chunk() メソッドがクエリに適用された take() 制限を無視し、すべての行がチャンクで処理されるために発生します。

限られた数の行 (例: 5 ユーザー) のみがチャンクで処理されるようにするために、指定された制限に達した後にチャンキング ループを中断するカスタム インデックス カウンターを実装できます。次のコードはこれを実現します:

class UserProcessor
{
    private int $index = 0;
    private int $limit = 5;

    public function process()
    {
        $query = \App\Models\User::query();

        $query->chunk(2, function ($users) {
            foreach ($users as $user) {
                $this->index++;

                // Process each user here
                // Example: $user->processData();

                if ($this->index >= $this->limit) {
                    // Stop processing after reaching the limit
                    return false;  // This will stop chunking
                }
            }
        });
    }
}

注意

$index と $limit はクラスのプロパティであり、use($index, $limit) でクロージャに渡されるメソッド変数ではありません。これは、 use() 経由で渡された変数が値によってクロージャ オブジェクトにコピーされるためです。結果として、クロージャ内の変更は元の値に影響を与えません。そのため、反復間で変更を適切に更新および追跡するには、それらをクラス プロパティにする必要があります。

以上がLaravel クエリの最適化: データをチャンクする正しい方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。