DELUNE - TRUNCATE


35

Ben DELETEve TRUNCATEkomutları arasındaki farklar hakkında daha iyi bir anlayış kazanmaya çalışıyorum . İçseller hakkındaki düşüncelerim, şu çizgide bir şeyler gösteriyor:

DELETE-> veritabanı motoru, satırı ilgili veri sayfalarından ve satırın girildiği tüm dizin sayfalarından bulur ve kaldırır. Bu nedenle, dizinler ne kadar fazla olursa silme o kadar uzun sürer.

TRUNCATE -> basitçe tüm tablonun veri sayfalarını kaldırır ve bunu bir tablonun içeriğini silmek için daha verimli bir seçenek haline getirir.

Yukarıdakilerin doğru olduğunu varsayarak (lütfen değilse düzeltin):

  1. Farklı kurtarma modları her bir ifadeyi nasıl etkiler? Hiç bir etkisi varsa
  2. Silme işleminde tüm dizinler taranıyor mu, yoksa yalnızca satırın bulunduğu yerler mi? Tüm indekslerin tarandığını (ve aranmadığını mı sanıyorum)?
  3. Komutlar nasıl çoğaltılır? SQL komutu her abone için gönderiliyor ve işleniyor mu? Yoksa MSSQL bundan biraz daha zeki midir?

2
Hemen önce -ing'in yararına ilişkin bu sorunun cevabında DELETEve üzerinde bazı bilgiler bulunmaktadır . Bu cevapta açıklanan tekniği kullanarak her iki komutun etkilerini incelemek için kayıt defterinde kendiniz de gezinebilirsiniz . TRUNCATETRUNCATEDROP
Nick Chammas

1
Bu cevap , DELETE ve TRUNCATE işlemlerinin içindekilerini gösterir. Ayrıca soru TRUNCATE'in daha iyi çalıştığı belirli bir durumu göstermektedir.
12'de

5
@ idtam TRUNCATEgeri alınabilir. Nick, sorduğu cevaba cevabını kapsar .
Mark Storey-Smith,

Kısalt "tablo değiştirme" izni gerektirir (kısaltmanın silinmek üzere yerine takıldığı anlamına gelir).
crokusek

Yanıtlar:


58

SİL -> veritabanı motoru, satırı ilgili veri sayfalarından ve satırın girildiği tüm dizin sayfalarından bulur ve kaldırır. Bu nedenle, dizinler ne kadar fazla olursa silme o kadar uzun sürer.

Evet, burada iki seçenek var. Satırlar, kümelenmemiş dizinlerden, satır taban tablosunu silen aynı işleç tarafından silinebilir. Bu, dar (veya satır başına) bir güncelleme planı olarak bilinir:

Satır başına silme

Veya kümelenmemiş dizin silme işlemleri, kümelenmemiş dizin başına bir tane olmak üzere, ayrı operatörler tarafından gerçekleştirilebilir. Bu durumda (geniş ya da endeks başına güncelleme planı olarak bilinir), tüm eylemler dizisi başına bir kez oynatılmadan önce bir çalışma masasında (istekli biriktirme) depolanır, genellikle sıralı olarak teşvik etmek için belirli kümelenmemiş dizinin tuşları tarafından açıkça sıralanır erişim düzeni

Endeks silme başına

TRUNCATE -> sadece tüm tablo veri sayfalarını topluca kaldırır ve bu da tablo içeriğini silmek için daha verimli bir seçenek olmasını sağlar.

Evet. TRUNCATE TABLEbirkaç nedenden dolayı daha verimlidir:

  1. Daha az kilit gerekebilir. Kısaltma tipik olarak, masa seviyesinde sadece tek bir şema modifikasyon kilidi gerektirir (ve her ölçüde ayrılan özel kilitler ). Silme, daha düşük bir (satır veya sayfa) ayrıntı düzeyinde kilitlerin yanı sıra, ayrılmamış sayfalardaki özel kilitleri de alabilir .
  2. Yalnızca kesme, tüm sayfaların yığın tablosundan çıkarılmasını garanti eder. Silme işlemi, özel bir tablo kilit ipucu belirtilmiş olsa bile (örneğin, veritabanı için bir satır sürümleme yalıtım düzeyi etkinleştirilmişse) yığın halinde boş sayfalar bırakabilir.
  3. Kısaltma daima minimum düzeyde kaydedilir (kullanılan kurtarma modelinden bağımsız olarak). İşlem günlüğüne sadece sayfa değiştirme işlemleri kaydedilir.
  4. Kısaltma , nesne 128 boyutunda veya daha büyükse ertelenmiş düşüşü kullanabilir . Ertelenen düşme, fiili yerinden çıkarma çalışmasının bir arka plan sunucusu iş parçacığı tarafından eşzamansız gerçekleştirildiği anlamına gelir.

Farklı kurtarma modları her bir ifadeyi nasıl etkiler? Herhangi bir etkisi var mı?

Silme işlemi her zaman tam olarak kaydedilir (silinen her satır işlem günlüğüne kaydedilir). Kurtarma modeli dışındakilerden farklıysa, günlük kayıtlarının içeriğinde bazı küçük farklılıklar vardır FULL, ancak bu hala teknik olarak tam kayıtlıdır.

Silme işleminde tüm dizinler taranıyor mu, yoksa yalnızca satırın bulunduğu yerler mi? Tüm indekslerin tarandığını (ve aranmadığını mı sanıyorum)?

Bir dizindeki bir satırı silmek (daha önce gösterilen dar veya geniş güncelleme planlarını kullanarak) her zaman bir anahtar (arama) ile erişimdir. Silinen her satır için tüm dizinin taranması korkunç derecede verimsiz olacaktır. Daha önce gösterilen dizin başına güncelleme planına tekrar bakalım:

Geniş plan 2

Yürütme planları talebe bağlı boru hatlarıdır: ebeveyn operatörler (sola), alt operatörleri onlardan bir seferde bir satır talep ederek çalışma yapmaya yönlendirir. Sıralama işleçleri engelliyor (ilk sıralanan satırı oluşturmadan önce tüm girişlerini kullanmaları gerekir), ancak yine de ilk satırı isteyen üst öğelerini (Dizin Silme) kullanıyorlar. Dizin Silme , her sıra için hedef kümelenmemiş dizini güncelleyerek, tamamlanan Sırala'dan bir anda bir satır çeker .

Geniş bir güncelleme planında, temel tablo güncelleme operatörü tarafından satır akışına eklenen sütunları göreceksiniz. Bu durumda, Kümelenmiş Dizin Silme, akışa kümelenmemiş dizin anahtarı sütunları ekler. Bu veri, depolama motoru tarafından kümelenmemiş dizinden kaldırılacak satırı bulmak için gereklidir:

Çıktı listesi detayı

Komutlar nasıl çoğaltılır? SQL komutu her abone için gönderiliyor ve işleniyor mu? Yoksa SQL Server bundan biraz daha akıllı mı?

İşlem veya birleştirme çoğaltması kullanılarak yayımlanan bir tabloda kesmeye izin verilmez . Silme işlemlerinin nasıl çoğaltıldığı, çoğaltma türüne ve nasıl yapılandırıldığına bağlıdır. Örneğin, anlık görüntü çoğaltması yalnızca toplu yöntemleri kullanarak tablonun belirli bir zamandaki görünümünü çoğaltır - artımlı değişiklikler izlenmez veya uygulanmaz. İşlem çoğaltma, günlük kayıtlarını okuyarak ve değişiklikleri abonelerde uygulamak için uygun işlemleri oluşturarak çalışır. Birleştirme çoğaltması, tetikleyicileri ve meta veri tablolarını kullanarak değişiklikleri izler.

İlgili okuma: Veriyi değiştiren T-SQL sorgularını optimize etmek

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.