« Tüm yayınlar

PostgreSQL'de CTE ile Toplu UPSERT: 90 Saniyeden 5 Saniyeye

Değişiklik geçmişi tutan e-posta senkronizasyon işlemi, ayrı sorgular yerine tek bir CTE sorgusuna taşınarak 100 bin kayıtta 90 saniyeden 5 saniyeye indirildi.

Bir Go/PostgreSQL projesinde, dosyadan gelen e-posta adreslerinin veritabanında aktif/pasif durumunu güncelleyip her değişikliği bir denetim (audit) tablosuna kaydeden bir senkronizasyon işlemi ele alınıyor. İlk uygulamada UNNEST ile toplu UPSERT, ayrı bir deaktivasyon sorgusu ve ayrı geçmiş kayıt sorguları kullanılıyordu; bu da 100 bin adres için yaklaşık 90 saniye sürüyordu. Asıl darboğaz, uygulama ile veritabanı arasında birden fazla gidiş-dönüş yapılması ve ara sonuçların (etkilenen ID'ler) ağ üzerinden taşınmasıydı.

Çözüm, tüm mantığı tek bir sorguda birleştiren zincirleme CTE (Common Table Expression) yapısına geçmek oldu. Yeni sorguda; girdi verisi bir CTE'de toplanıyor, pasifleştirme UPDATE'i çalışıyor, UPSERT INSERT ile aktifleştirme yapılıyor, ardından hem aktifleştirilen hem de pasifleştirilen kayıtlar için geçmiş tablosuna INSERT işlemleri aynı CTE zinciri içinde gerçekleştiriliyor. Sonuçta uygulama tarafına yalnızca aktifleştirilen ve pasifleştirilen kayıt sayıları dönüyor.

Bu değişiklik sonucunda performans önemli ölçüde iyileşti: 10 bin kayıt ~5 saniyeden ~3 saniyeye, 100 bin kayıt ~90 saniyeden ~5 saniyeye düştü, 1 milyon kayıt ise yaklaşık 30 saniyede işlenebildi. Bu örnek, veritabanı ile uygulama katmanı arasındaki gidiş-dönüş sayısını azaltmanın — özellikle sqlc gibi tip güvenli sorgu üretici araçlarla çalışan Go geliştiricileri için — toplu veri işleme senaryolarında ne denli kritik bir performans kazanımı sağlayabileceğini somut biçimde gösteriyor.

» KaynakDev.to