2864ms → ~400ms hedefi
26 Aralık 2025 - v3 (Dinamik güncellemeler dahil)
Şu anda her şarkı kartı için "Bu favorilerde mi?" diye ayrı ayrı soruyoruz. Bunun yerine sayfa açılırken tüm favorileri tek seferde çekip JavaScript'e vereceğiz. Kullanıcı favori eklerse anında güncellenir, sayfa yenilemeye gerek kalmaz.
Şu anda her playlist/albüm için "Kaç şarkı var? Toplam süre ne?" diye ayrı ayrı hesaplıyoruz. Bu çok yavaş. Bunun yerine bu bilgiyi önceden hesaplayıp saklayacağız.
Örnek: Bir playlist'te 50 şarkı var. Her seferinde saymak yerine, tabloya "songs_count: 50, total_duration: 10800" yazacağız. Yeni şarkı eklenince bu sayıları otomatik güncelleyeceğiz.
database/migrations/tenant/
// muzibu_playlists tablosu
$table->unsignedInteger('songs_count')->nullable();
$table->unsignedInteger('total_duration')->nullable();
// NULL = henüz hesaplanmamış (eski veri)
// 0 = hesaplandı, gerçekten 0
Not: Central'a eklemeye gerek yok çünkü muzibu_playlists/albums sadece tenant DB'de.
Playlist.php, Album.php
// getSongsCountAttribute()
if ($this->attributes['songs_count'] === null) {
$count = $this->songs()->count();
$this->updateQuietly(['songs_count' => $count]);
return $count;
}
return $this->attributes['songs_count'];
Nasıl çalışır: İlk çekildiğinde null ise hesaplar ve DB'ye yazar. Sonraki isteklerde direkt DB'den okur (query yok).
Modules/Muzibu/app/Observers/SongObserver.php
| created() | → Album songs_count++, total_duration += duration |
| deleted() | → Album songs_count--, total_duration -= duration |
| updated() | → duration değiştiyse total_duration güncelle |
| restored() | → Soft delete'den geri gelirse ekle |
Playlist-Song pivot tablosu için
| attach() | → Playlist songs_count++, total_duration += song.duration |
| detach() | → Playlist songs_count--, total_duration -= song.duration |
Not: Playlist many-to-many ilişkisi olduğu için pivot event'lerini yakalamalıyız.
İlk çalıştırma + eski veri fix
php artisan muzibu:recalculate-counts
// Tüm playlist ve album'leri tarar
// songs_count ve total_duration hesaplar
// Progress bar ile gösterir
Ne zaman kullanılır:
• Eski DB'den veri import edilince
• Manuel düzeltme gerekince
• Tutarsızlık tespit edilince
3 query → Session
Aynı kullanıcının subscription'ı 3 kez sorgulanıyor. Session'a cache'le.
27ms → Session
Kurumsal hesap kontrolü de session'a alınabilir.
P1: Favorites N+1 Çözümü
En kolay, en büyük kazanç (174 query → 1)
P2: Migration oluştur ve çalıştır
songs_count + total_duration nullable field'lar
P2: Model accessor'ları ekle
Lazy calculation - null ise hesapla
P2: Observer'ları oluştur
Song + Playlist pivot event'leri
P2: Recalculate command
Mevcut verileri hesapla
Test & Karşılaştırma
Telescope'da query sayısı kontrolü
Bu plan onaylanırsa P1'den başlayarak uygulamaya geçeceğim.