ProgramlamaSQL DBA, Backend geliştirici

Büyük tabloların (milyonlarca satır) toplu silinmesini veya temizlenmesini SQL'de nasıl doğru bir şekilde uygulayabiliriz, böylece kilitlenmeleri en aza indirir, işlem günlüğünü aşırı yüklemez ve performansta kayıp yaşamayız?

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

Yanıt.

On milyonlarca satırın toplu olarak silinmesi, özellikle yüksek yük altındaki veritabanlarında tipik ve en tehlikeli işlemlerden biridir. Tarihsel olarak, birçok kişi sadece DELETE FROM yazmış ve bu durum, tablo kilitlenmelerine ve işlem günlüğünün taşmasına sebep olmuştur. Ana sorun: işlem çok büyük hale gelir, hizmet eden süreçler yavaşlar ve geri alma sonuçları tahmin edilemez olabilir.

Çözüm — "parti" (batch) silme uygulamak, kısa işlemlerle döngüde az sayıda satırı işlemek için, kilitlenmeleri ve sistem üzerindeki etkiyi en aza indirmektir:

Örnek kod (SQL Server):

WHILE 1=1 BEGIN DELETE TOP (10000) FROM YourHugeTable WHERE CreatedAt < DATEADD(year,-2,GETDATE()); IF @@ROWCOUNT = 0 BREAK; WAITFOR DELAY '00:00:01'; -- yükü azaltmak için küçük bir ara END

Anahtar özellikler:

  • Kilitlerin boyutu ve işlem günlüğüne yazma en aza indirilir.
  • İşlem küçük parçalar halinde yürütülür: sistem yanıt verir durumda kalır.
  • İlerleme gösterimi veya dış izleme mantığı ile birleştirilebilir.

Şaşırtıcı Sorular.

DELETE yerine TRUNCATE yaparsak, her zaman daha hızlı ve güvenli midir?

Hayır. TRUNCATE çok daha hızlıdır, ancak :

  1. TRUNCATE, tabloya dış anahtar referansı varsa uygulanamaz.
  2. TRUNCATE tetikleyicileri çağırmaz.
  3. TRUNCATE, koşul yerine tüm satırları tamamen siler.

Toplu DELETE'de filtre alanı üzerine indeks kullanmak önemli midir?

Evet, filtre sütununa (örneğin CreatedAt) uygun bir indeksin bulunması, silinecek satırların aranmasını hızlandırır ve tablo üzerindeki yükü azaltır. İndeks olmadan, sorgu tabloyu tamamen etkiler, her parçada az sayıda satır silinmesine rağmen.

CREATE INDEX idx_createdat ON YourHugeTable(CreatedAt);

Birden fazla işlem aynı anda toplu DELETE yaparsa ne olur?

Bu, kilitler için rekabete yol açar: kilit yükselmeleri, bekleme süresinin artması ve deadlock olasılığı doğar. Bir tablodan toplu silme, tek bir işlemle veya çok dikkatli bir şekilde bölünmüş aralıklarla gerçekleştirilmelidir.

Tipik Hatalar ve Antipatternler

  • Tek bir işlemle toplu silme (tabloyu kilitler, işlem günlüğünü taşır).
  • İlerleme kontrolü ve çalışma süresinin kontrolü eksikliği.
  • İndekslerin yokluğu — her seferinde tam tablo taranır.

Hayattan Bir Örnek

Negatif Durum

DBA, DELETE FROM Log WHERE dt < '2021-01-01' ifadesiyle 60 milyon satır içeren bir tabloyu temizlemeye karar verdi. Sunucu neredeyse "dondu", diğer süreçler işlemin tamamlanmasını beklemeye başladı, günlük dosyası keskin bir şekilde büyüdü, geri yükleme uzun sürdü.

Artılar:

  • Uygulaması kolay.

Eksiler:

  • Sunucu genelinde önemli bir performans düşüşü; arıza durumunda veri kaybı riski, geri yükleme uzun sürüyor.

Pozitif Durum

Silme, 10,000 satırlık partilere bölündü; işlem kontrol altında, her parçadan sonra ara verildi. Sunucu istikrarlı bir şekilde çalışıyor, diğer görevler yerine getiriliyor, admin ilerlemeyi izliyor.

Artılar:

  • Önemli bir performans kaybı yok.
  • Günlük taşma riski yok.

Eksiler:

  • İşlem tamamlanmak için daha fazla zaman alıyor, tekrarlar için ek otomasyon gerektiriyor.