Lebih baik gunakan chunkById daripada chunk untuk mengelakkan baris hilang semasa kemas kini kelompok. Menggunakan bongkah boleh mengalihkan offset pertanyaan berikutnya selepas mengemas kini baris, menyebabkan baris yang tidak diproses dilangkau.
Contohnya:
Post::where('processed', 0)->chunk(100, function($posts) { foreach($posts as $post) { $post->processed = 1; $post->save(); } });
Kod di atas menjana pertanyaan berikut.
select * from `posts` where `processed` = 0 limit 100 offset 0 select * from `posts` where `processed` = 0 limit 100 offset 100 ...
Bahagian pertama mengemas kini 100 baris. Pertanyaan kedua, tanpa menyedari perkara ini, melangkau 100 baris yang belum diproses kerana ia masih menggunakan ofset.
Perkara di atas dijelaskan secara terperinci oleh
Thai Nguyen Hung
Apabila cuba memproses bilangan baris yang terhad menggunakan kaedah chunk() Laravel, kami mungkin menjangkakan kod berikut akan memproses hanya 5 pengguna dalam kelompok 2:
$query = \App\Models\User::query()->take(5); $query->chunk(2, function ($users) { // Process users });
Walau bagaimanapun, ini akan memproses semua pengguna dalam pangkalan data, dua pada satu masa. Ini berlaku kerana kaedah chunk() Laravel mengabaikan had take() yang digunakan pada pertanyaan, menyebabkan semua baris diproses dalam ketulan.
Untuk memastikan bahawa hanya bilangan baris yang terhad (cth., 5 pengguna) diproses dalam bongkah, kami boleh melaksanakan pembilang indeks tersuai yang akan memecahkan gelung chunking selepas mencapai had yang ditentukan. Kod berikut mencapai ini:
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 } } }); } }
Nota
$index dan $limit ialah sifat kelas, bukan pembolehubah kaedah yang dihantar ke penutupan dengan penggunaan($index, $limit). Ini kerana pembolehubah yang diluluskan melalui use() disalin ke dalam objek penutupan mengikut nilai. Akibatnya, sebarang pengubahsuaian dalam penutupan tidak akan menjejaskan nilai asal, sebab itu ia mestilah sifat kelas untuk mengemas kini dan menjejaki perubahan dengan betul merentas lelaran.
Atas ialah kandungan terperinci Mengoptimumkan Pertanyaan Laravel: Cara Yang Betul untuk Memotong Data. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!