Büyük miktarda veriyi Laravel ile işlerken bellek hataları ya da sunucu zaman aşımı sorunları ile karşılaştıysanız, bu makale tam size göre.
Bu durumu, büyük bir CSV verisinin üretim ortamında Apache zaman aşımı hatalarına neden olmasıyla öğrendim. İşte sonuçta karşılaştığım problemler.
Problem
Problem
// ❌ Bu büyük tablolar için çökmesine neden olur
$users = User::all();
foreach ($users as $user) {
// işle...
}
all(), tüm satırları bir kerede belleğe yükler. 100,000+ satırda sunucunuz bellek yetersizliğinden dolayı hata verecektir.
1. chunk() — Partlar Halinde İşleme
1. chunk() — Partlar Halinde İşleme
User::chunk(500, function ($users) {
foreach ($users as $user) {
// 500 satırı bir kerede işler
}
});
✅ Bellek düşük kalır
✅ Arka plan işleri için uygundur
⚠️ chunk() içinde satırları değiştirmeyin/silin, kayıtlarda atlamalara yol açabilir.
⚠️ Birden fazla SQL sorgusu gerçekleştirir.
Kullanım alanları: e-posta gönderimleri, arka plan işlemleri
2. chunkById() — chunk()’ün Daha Güvenli Versiyonu
2. chunkById() — chunk()’ün Daha Güvenli Versiyonu
User::chunkById(500, function ($users) {
foreach ($users as $user) {
// satır güncellerken güvenli
}
});
✅ Satırları güncellemek/silmek için güvenlidir
✅ chunk()’ten daha güvenilir
Kullanım alanları: büyük miktarda kayıt güncelleme veya silme
3. cursor() — Tek Satır İşleme
3. cursor() — Tek Satır İşleme
foreach (User::cursor() as $user) {
// bir satırı işler
}
✅ Bellek verimliliği en yüksek
✅ Sadece bir SQL sorgusu
❌ Eager loading kullanılamaz (with())
❌ Veritabanı bağlantısı sürekli açık kalır
Kullanım alanları: salt okuma işlemleri, CSV dışa aktarma
4. lazy() — İki Yöntemin En İyisi
4. lazy() — İki Yöntemin En İyisi
foreach (User::lazy() as $user) {
// arka planda parçalar, cursor() gibi hissettirir
}
✅ Bellek verimliliği
✅ Eager loading (with()) destekler
✅ Daha temiz bir sözdizimi
// Eager loading ile ✅
User::with()->lazy()->each(function ($user) {
// işle
});
Kullanım alanları: cursor() kullanmanız gerektiğinde fakat ilişkilerin de yüklenmesi gerektiğinde
Hızlı Karşılaştırma Tablosu
Hızlı Karşılaştırma Tablosu
| Yöntem | Bellek | SQL Sorguları | with()’ü Destekler | Değiştirmeye Güvenli? |
|---|---|---|---|---|
| all() | ❌ Yüksek | 1 | ✅ | ✅ |
| chunk() | ✅ Düşük | Birden Fazla | ✅ | ⚠️ Hayır |
| chunkById() | ✅ Düşük | Birden Fazla | ✅ | ✅ Evet |
| cursor() | ✅ En Düşük | 1 | ❌ | ✅ |
| lazy() | ✅ Düşük | Birden Fazla | ✅ | ✅ |
Gerçek Dünya Örneğim
Gerçek Dünya Örneğim
Bu, CSV dışa aktarma üzerindeki Apache zaman aşımı sorunumu çözdü:
// ❌ Önce — zaman aşımına neden oldu
$users = User::all();
// ✅ Sonra — mükemmel çalışıyor
foreach (User::cursor() as $user) {
fputcsv($handle, [
$user->name,
$user->email,
$user->created_at
]);
}
Özet
Özet
- chunk() — toplu işler, e-posta gönderimleri
- chunkById() — toplu veri değiştirme işlemleri
- cursor() — okuma temelli işlemler, CSV dışa aktarmalar, en yüksek bellek verimliliği
- lazy() — cursor() ile ilişkilendirilmiş yüklemeleri gerektiğinde
Daha derinlemesine bilgi istiyorsanız, ücretsiz Laravel eğitim sitemdeki tam derse göz atabilirsiniz:
https://php-laravel-tutorials.netlify.app/lesson-laravel-large-data
Kaynak: Orijinal Makale


