優化 Laravel 查詢:分塊資料的正確方法

王林
發布: 2024-09-09 06:31:38
原創
693 人瀏覽過

Optimizing Laravel Queries: The Right Way to Chunk Data

為什麼應該避免使用塊?

最好使用 chunkById 而不是 chunk 以避免批量更新時丟失行。使用 chunk 可以在更新行後移動後續查詢的偏移量,導致跳過未處理的行。

例如:

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 行。第二個查詢沒有意識到這一點,因此跳過 100 個未處理的行,因為它仍然使用偏移量。

以上由
詳細解釋 太阮雄

如何對有限數量的行進行分塊?

當嘗試使用 Laravel 的 chunk() 方法處理有限數量的行時,我們可能會期望以下程式碼以 2 為一組僅處理 5 個使用者:

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

$query->chunk(2, function ($users) {
  // Process users
});
登入後複製

但是,這將處理資料庫中的所有用戶,一次兩個。發生這種情況是因為 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中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!