ProgramlamaBackend Geliştirici, Veri Mühendisi

SQL'de çok sayıda koşulla ilişkili tabloları toplu olarak güncellerken (Bulk UPDATE) deadlock, veri kaybını önlemek ve performansı maksimize etmek için nasıl doğru bir şekilde uygulama yapılır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Bulk UPDATE, ilişkili tablolardaki büyük veri setlerinin değiştirildiği kritik bir işlemdir. SQL tarihinde tipik uygulama, iç sorgu veya JOIN ile yapılan UPDATE'dir. Problemler: Herhangi bir toplu güncelleme işlemi, sıralama kontrolü olmaksızın birçok satırı bloke eder, kilitlerin yükselmesine neden olur ve birden çok güncelleme durumunda deadlock'a yol açabilir.

Çözüm:

  • Her zaman UPDATE'yi küçük partilere (örneğin, birincil anahtar veya tarih aralıklarına göre) bölün.
  • JOIN üzerinden SET tabanlı yaklaşımlar kullanın, ancak sınırsız toplu güncellemeden kaçının.
  • Filtreleri akıllıca uygulayın, WHERE koşullarına göre alanları indeksleyin, ilişkili tablolar için işlem sırasını dikkate alın.

Kod örneği (PostgreSQL):

UPDATE Orders o SET status = 'archived' FROM Customers c WHERE o.customer_id = c.id AND c.closed = TRUE AND o.status != 'archived';

Veya partiler halinde:

WITH upd AS ( SELECT o.id FROM Orders o JOIN Customers c ON o.customer_id = c.id WHERE c.closed = TRUE AND o.status != 'archived' LIMIT 10000 ) UPDATE Orders SET status = 'archived' WHERE id IN (SELECT id FROM upd);

Önemli noktalar:

  • "Tüm tabloyu anında güncellemeden" kaçının — her zaman partilere ayırın.
  • Güncellenen ve filtreleme alanlarında indeks kullanın.
  • Seçim koşullarını net bir şekilde belirleyin, gereksiz satırların toplu güncellenmesinden kaçının.

Enteresan sorular.

Eğer benzer tabloları bölgesel ayrım veya ters filtreler olmaksızın eşzamanlı olarak UPDATE ederseniz ne olur?

Muhtemel deadlock meydana gelir: süreçler aynı satırları bloke eder ve birbirini bekler. Kaçınmak için — partilerin kesişmemesi veya kesinlikle ardışık olarak çalıştırılması gerekir.

Masaüstü güncellemeleri JOIN aracılığıyla yapmak ve alt sorgu ile yapmak arasında fark var mı?

Uygun indeksler varsa, ana fark sadece okunabilirlikte ve bazen belirli bir DBMS'nin performansında ortaya çıkıyor. JOIN genellikle daha hızlıdır çünkü optimizöre daha iyi bir plan oluşturma imkanı tanır.

Ne zaman TRUNCATE/DELETE'yi UPDATE yerine kullanmak güncel?

Eğer iş mantığı buna izin veriyorsa — örneğin, arşiv kayıtlarını fiziksel olarak silmek veya tabloyu sıfırlamak gerekiyorsa, sadece durum bayrağını değiştirmek değil. Ancak durum güncellemeleri için sadece UPDATE kullanmalısınız.

Tipik hatalar ve anti-paternler

  • "Filtre olmadan" toplu UPDATE: kilitlenmeler, geri alma, deadlock.
  • İndekslerin olmaması — tabloları tamamen tarama.
  • Anahtarlar üzerinden bölmeden paralel olarak UPDATE başlatma.

Gerçek hayattan bir örnek

Negatif vaka

Büyük bir e-ticaret sitesinde, siparişler ve alıcıların durumunu değiştirmek için birden fazla UPDATE başlatıldı, intervü'lamalamaya göre bölmeden. Sonuç: karşılıklı blokajlar, birkaç kez zorunlu geri alma gerekti ve kaydedilmemiş veriler geri alındı.

Artılar:

  • Her şey bir sorguda.

Eksiler:

  • Deadlock olasılığı, performans kaybı, küçük bir hata ile büyük veri yığınları geri alınıyor.

Pozitif vaka

Büyük örnekler partilere ayrıldı, kesinlikle ardışık olarak çalıştırıldı, yalnızca filtreye göre gerekli satırlar işlendi.

Artılar:

  • Veritabanının kararlı çalışması.
  • Performans etkilenmiyor.

Eksiler:

  • Daha fazla kod hacmi, partilerin yürütülmesi için izleme gerektiriyor.