SQL Server, birden çok satırı etkileyen (veya etkileyebilecek) bir güncelleştirmenin parçası olarak benzersiz bir dizini korurken işleçlerin her zaman Böl, Sırala ve Daralt kombinasyonunu kullanır .
Sorudaki örnek üzerinden çalışarak, mevcut dört satırın her biri için güncellemeyi ayrı bir tek satırlık güncelleme olarak yazabiliriz:
-- Per row updates
UPDATE dbo.Banana SET pk = 2 WHERE pk = 1;
UPDATE dbo.Banana SET pk = 3 WHERE pk = 2;
UPDATE dbo.Banana SET pk = 4 WHERE pk = 3;
UPDATE dbo.Banana SET pk = 5 WHERE pk = 4;
Sorun, ilk ifadenin pk
1'den 2'ye değişmesi ve zaten pk
= 2 olduğu bir satır olması nedeniyle başarısız olacağıdır . SQL Server depolama motoru, benzersiz dizinlerin tek bir deyimde bile işlemenin her aşamasında benzersiz kalmasını gerektirir . Böl, Sırala ve Daralt tarafından çözülen sorun budur.
Bölünmüş
İlk adım, her güncelleme deyimini bir silme ve ardından bir ekleme olarak bölmektir:
DELETE dbo.Banana WHERE pk = 1;
INSERT dbo.Banana (pk, c1, c2) VALUES (2, 'A', 'W');
DELETE dbo.Banana WHERE pk = 2;
INSERT dbo.Banana (pk, c1, c2) VALUES (3, 'B', 'X');
DELETE dbo.Banana WHERE pk = 3;
INSERT dbo.Banana (pk, c1, c2) VALUES (4, 'C', 'Y');
DELETE dbo.Banana WHERE pk = 4;
INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');
Bölme işleci akışa bir eylem kodu sütunu ekler (burada Act1007 olarak etiketlenmiştir):
İşlem kodu güncelleme için 1, silme için 3 ve ekleme için 4'tür.
Çeşit
Yukarıdaki bölünmüş ifadeler yine de yanlış geçici benzersiz anahtar ihlali üretecektir, bu nedenle bir sonraki adım, ifadeleri güncellenen benzersiz dizinin anahtarlarına ( pk
bu durumda) ve ardından eylem koduna göre sıralamaktır. Bu örnek için bu, aynı anahtardaki silme işlemlerinin (3), ekleme işleminden (4) önce sıralandığı anlamına gelir. Ortaya çıkan sipariş:
-- Sort (pk, action)
DELETE dbo.Banana WHERE pk = 1;
DELETE dbo.Banana WHERE pk = 2;
INSERT dbo.Banana (pk, c1, c2) VALUES (2, 'A', 'W');
DELETE dbo.Banana WHERE pk = 3;
INSERT dbo.Banana (pk, c1, c2) VALUES (3, 'B', 'X');
DELETE dbo.Banana WHERE pk = 4;
INSERT dbo.Banana (pk, c1, c2) VALUES (4, 'C', 'Y');
INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');
Çöküş
Önceki aşama, tüm durumlarda yanlış benzersizlik ihlallerinden kaçınmayı garanti etmek için yeterlidir. Bir optimizasyon olarak, Daralt bitişik silmeleri ve aynı anahtar değerindeki eklemeleri bir güncellemede birleştirir:
-- Collapse (pk)
DELETE dbo.Banana WHERE pk = 1;
UPDATE dbo.Banana SET c1 = 'A', c2 = 'W' WHERE pk = 2;
UPDATE dbo.Banana SET c1 = 'B', c2 = 'X' WHERE pk = 3;
UPDATE dbo.Banana SET c1 = 'C', c2 = 'Y' WHERE pk = 4;
INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');
pk
2, 3 ve 4 değerleri için silme / ekleme çiftleri , bir güncellemede birleştirilerek pk
= 1 üzerinde tek bir silme ve pk
= 5 için bir ekleme bırakılmıştır .
Daralt işleci satırları anahtar sütunlarına göre gruplandırır ve eylem kodunu daraltma sonucunu yansıtacak şekilde güncelleştirir:
Kümelenmiş Dizin Güncellemesi
Bu operatör Güncelleme olarak etiketlenmiştir, ancak ekleme, güncelleme ve silme yeteneğine sahiptir. Satır başına Kümelenmiş Dizin Güncelleştirmesi tarafından hangi eylemin gerçekleştirileceği, bu satırdaki eylem kodunun değerine göre belirlenir. Operatörün bu çalışma modunu yansıtan bir Action özelliği vardır:
Satır değişiklik sayaçları
Yukarıdaki üç güncellemenin , korunan benzersiz dizinin anahtar (lar) ını değiştirmediğini unutmayın . Aslında , dizindeki anahtar sütunlara yönelik güncellemeleri, anahtar olmayan sütunların ( c1
ve c2
) yanı sıra bir silme ve bir ekleme güncellemelerine dönüştürdük. Ne silme ne de bir ekleme, benzersiz bir benzersiz anahtar ihlaline neden olamaz.
Bir ekleme veya silme, satırdaki her bir sütunu etkiler; bu nedenle, her sütunla ilişkili istatistiklerde değişiklik sayaçları artar. Güncelleme (ler) için, yalnızca önde gelen sütun olarak güncellenmiş sütunlardan herhangi birine sahip istatistiklerde değişiklik sayaçları artırılır (değer değişmemiş olsa bile).
Bu nedenle istatistik satırı değişiklik sayaçları pk
, 2 için ve 5 c1
ve için değişiklikler gösterir c2
:
-- Collapse (pk)
DELETE dbo.Banana WHERE pk = 1; -- All columns modified
UPDATE dbo.Banana SET c1 = 'A', c2 = 'W' WHERE pk = 2; -- c1 and c2 modified
UPDATE dbo.Banana SET c1 = 'B', c2 = 'X' WHERE pk = 3; -- c1 and c2 modified
UPDATE dbo.Banana SET c1 = 'C', c2 = 'Y' WHERE pk = 4; -- c1 and c2 modified
INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z'); -- All columns modified
Not: Yalnızca temel nesneye (yığın veya kümelenmiş dizin) uygulanan değişiklikler, istatistik satırı değişiklik sayaçlarını etkiler. Kümelenmemiş dizinler, temel nesnede önceden yapılan değişiklikleri yansıtan ikincil yapılardır. İstatistik satırı değişiklik sayaçlarını hiç etkilemezler.
Bir nesnenin birden fazla benzersiz dizini varsa, her bir güncelleştirmeyi düzenlemek için ayrı bir Böl, Sırala, Daralt kombinasyonu kullanılır. SQL Server, bu durumu kümelenmemiş dizinler için Bölme sonucunu bir İstekli Tablo Biriktirmesine kaydedip, her bir benzersiz dizin (bu kendi dizinlerine göre sırala + eylem kodu ve Daralt özelliğine sahip olacak) için ayarlanan kümeyi yeniden oynatarak optimize eder.
İstatistik güncellemelerine etkisi
Otomatik istatistik güncellemeleri (etkinleştirilmişse), sorgu optimize edici istatistiksel bilgilere ihtiyaç duyduğunda ve mevcut istatistiklerin güncel olmadığını (veya şema değişikliği nedeniyle geçersiz olduğunu) fark ettiğinde gerçekleşir . Kaydedilen değişiklik sayısının bir eşiği aştığı durumlarda istatistikler güncel değildir.
Böl / Sırala / Daralt düzenlemesi beklenenden farklı satır değişikliklerinin kaydedilmesine neden olur. Bu da bir istatistik güncellemesinin aksi durumda olduğundan daha erken veya daha sonra tetiklenebileceği anlamına gelir.
Yukarıdaki örnekte, anahtar sütunu için satır değişiklikleri 4 (etkilenen her tablo satırı için bir tane) veya 5 (Daralt tarafından oluşturulan her silme / güncelleme / ekleme için) yerine 2 (net değişiklik) artar.
Buna ek olarak, orijinal sorgu tarafından mantıksal olarak değiştirilmeyen anahtar olmayan sütunlar, güncellenen tablo satırlarının iki katına kadar (her silme için bir ve her ekleme için bir tane) sayılabilecek satır değişiklikleri biriktirir .
Kaydedilen değişiklik sayısı, eski ve yeni anahtar sütun değerleri arasındaki çakışma derecesine bağlıdır (ve böylece ayrı ayrı silme ve eklemelerin derecesi daraltılabilir). Her yürütme arasındaki tablo sıfırlandığında, aşağıdaki sorgular farklı çakışmalara sahip satır değiştirme sayaçları üzerindeki etkiyi gösterir:
UPDATE dbo.Banana SET pk = pk + 0; -- Full overlap
UPDATE dbo.Banana SET pk = pk + 1;
UPDATE dbo.Banana SET pk = pk + 2;
UPDATE dbo.Banana SET pk = pk + 3;
UPDATE dbo.Banana SET pk = pk + 4; -- No overlap