İstekli biriktirme işleci kümelenmiş bir sütun deposundan bu silme işlemi için yararlı mı?


28

Kümelenmiş bir sütun deposu dizininden veri silme testi yapıyorum.

Uygulama planında büyük bir istekli biriktirme operatörü olduğunu fark ettim:

görüntü tanımını buraya girin

Bu, aşağıdaki özelliklerle tamamlanmaktadır:

  • 60 milyon satır silindi
  • 1.9 GiB TempDB kullanılmış
  • 14 dakika yürütme süresi
  • Seri planı
  • 1 biriktirme yeniden bağlama
  • Tarama için tahmini maliyet: 364.821

Tahminciyi küçümseyecek şekilde kandırırsam, TempDB'yi kullanmaktan kaçınan daha hızlı bir plan elde ederim:

görüntü tanımını buraya girin

Tahmini tarama maliyeti: 56.901

(Bu tahmini bir plandır, ancak yorumlardaki sayılar doğrudur.)

Aşağıdakileri çalıştırarak delta depolarını yıkarsam ilginçtir, makara tekrar kaybolur:

ALTER INDEX IX_Clustered ON Fact.RecordedMetricsDetail REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);

Biriktirme, yalnızca delta depolarında bazı sayfa eşiklerinden daha fazlası olduğunda ortaya çıkar.

Delta mağazalarının boyutunu kontrol etmek için, tablo için satır içi sayfaları kontrol etmek üzere aşağıdaki sorguyu çalıştırıyorum:

SELECT  
  SUM([in_row_used_page_count]) AS in_row_used_pages,
  SUM(in_row_data_page_count) AS in_row_data_pages
FROM sys.[dm_db_partition_stats] as pstats
JOIN sys.partitions AS p
ON pstats.partition_id = p.partition_id
WHERE p.[object_id] = OBJECT_ID('Fact.RecordedMetricsDetail');

İlk plandaki makara yineleyicisine makul bir fayda var mı? Varlığının tutarlı olmadığı için bunun performans geliştirme amaçlı olduğunu ve cadılar bayramı koruması için tasarlanmadığını varsaymalıyım.

Bunu 2016 CTP 3.1'de test ediyorum, ancak 2014 SP1 CU3'te de aynı davranışı görüyorum.

Şema ve veri üreten bir senaryo yayınladım ve sorunu burada göstererek sizi yönlendirdim .

Soru, bu noktada, soruna neden olan sorun için bir geçici çözümüm olduğundan (büyük bir makara dolgulu TempDB), bu noktada optimizer davranışına dair meraktan mahrum. Şimdi bunun yerine bölüm değiştirme kullanarak siliyorum.


2
Ben denerseniz OPTION (QUERYRULEOFF EnforceHPandAccCard)biriktirme kaybolur. HP'nin "Cadılar Bayramı Koruması" olabileceğini varsayıyorum. Ancak daha sonra bu planı bir USE PLANipucu ile kullanmaya çalışmak (planı OPTIMIZE FOR geçici çözümden de kullanmaya çalışmak gibi) başarısız olur
Martin Smith

@ MartinSmith'e teşekkürler. Ne AccCardolacağı hakkında bir fikrin var mı? Artan sütun kardinalitesi kardinalite belki de?
James L

1
@JamesLupolt Hayır Beni özellikle ikna eden hiçbir şey bulamadım. Belki Acc, Biriktirme veya Erişimdir?
Martin Smith

Yanıtlar:


22

İlk plandaki makara yineleyicisine makul bir fayda var mı?

Bu, “makul” olarak kabul ettiğinize bağlıdır, ancak maliyet modeline göre cevap evetdir. Elbette bu doğrudur, çünkü optimizer daima bulduğu en ucuz planı seçer.

Asıl soru, maliyet modelinin neden biriktirme planını, plan yapılmadığından daha ucuza almasıdır. Delta deposuna herhangi bir satır eklenmeden önce, yeni bir tablo için oluşturulmuş tahmini planları (komut dosyanızdan) düşünün:

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE);

Bu plan için tahmini maliyet çok büyük 771,734 birimdir :

Asıl plan

Maliyetin neredeyse tamamı Kümelenmiş Dizin Sil ile ilişkilidir, çünkü silmelerin çok fazla rastgele G / Ç ile sonuçlanması beklenir. Bu sadece tüm veri değişikliklerine uygulanan genel bir mantıktır. Örneğin, bir b-ağacı indeksindeki sıralanmamış bir modifikasyon setinin, yüksek bir G / Ç maliyeti ile birlikte, büyük ölçüde rasgele G / Ç ile sonuçlandığı varsayılmaktadır.

Veri değiştirme planları, tam olarak bu maliyet nedenleriyle, sıralı erişimi teşvik edecek bir sıradaki satırları sunmak için bir Sıralama özelliğine sahip olabilir. Bu durumda etki, tablonun bölümlenmesi nedeniyle daha da artmaktadır. Aslında çok bölünmüş; senaryonuz bunlardan 15.000 tane yaratıyor. Çok bölümlenmiş bir tablodaki rastgele güncellemeler özellikle yüksek maliyetlidir çünkü bölümlere (satır kümeleri) geçiş akışının fiyatına yüksek maliyet de verilir.

Dikkate alınması gereken son ana faktör, yukarıdaki basit güncelleme sorgusunun ('güncelleme', silme dahil herhangi bir veri değiştirme işlemi anlamına gelir), aynı tarama satırında hem tarama hem de tarama için kullanılan "satır kümesi paylaşımı" adlı bir optimizasyona hak kazanmasıdır. Masanın güncellenmesi. Uygulama planı hala iki ayrı operatör gösteriyor, ancak yine de kullanılan tek bir satır kümesi var.

Bundan söz ediyorum, çünkü bu optimizasyonun uygulanabilmesi, optimizer'ın rasgele I / O maliyetini azaltmak için açıkça sıralamanın potansiyel faydalarını göz önünde bulundurmayan bir kod yolu kullandığı anlamına gelir . Masanın bir b-ağacı olduğu durumda, bu mantıklıdır, çünkü yapı doğal olarak sıralanmıştır, bu yüzden satır kümesini paylaşmak tüm potansiyel faydaları otomatik olarak sağlar.

Bunun önemli sonucu, güncelleme operatörü için maliyetlendirme mantığının, temel alınan nesnenin sütun deposu olduğu, bu sıralı faydayı (sıralı G / Ç'yi veya diğer optimizasyonları teşvik eden) dikkate almamasıdır. Bunun nedeni sütun deposu değişikliklerinin yerinde yapılmamasıdır; Bir delta deposu kullanıyorlar. Dolayısıyla maliyet modeli, b-ağaçlarındaki sütun sıralayıcılara karşı paylaşılan satır kümesi güncellemeleri arasındaki farkı yansıtıyor.

Bununla birlikte, (çok!) Bölümlenmiş bir sütun deposunun özel durumunda, korunmuş sipariş için hala bir avantaj olabilir, zira bir sonraki bölüme tüm güncellemeleri bir sonrakine geçmeden önce yapmak bir G / Ç açısından avantajlı olabilir. .

Standart maliyet mantığı burada sütun depoları için yeniden kullanılır, bu nedenle bölüm sırasını koruyan bir plan (her bölüm içindeki sırayla olmasa da) daha düşük maliyetlidir. Bunu, güncelleme sorgusuna sıralı giriş yapmak için belgelenmemiş izleme bayrağı 2332 kullanarak test sorgusunda görebiliriz. Bu DMLRequestSortözellik, güncelleme sırasında true olarak ayarlanır ve optimize ediciyi, bir sonraki bölüme geçmeden önce bir bölüm için tüm satırları sağlayan bir plan oluşturmaya zorlar:

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332);

Bu plan için tahmini maliyet 52.5174 birimde çok daha düşüktür :

DMLRequestSort = gerçek plan

Maliyetteki bu düşüş, güncellemedeki tahmini düşük G / Ç maliyetinden kaynaklanmaktadır. Sunulan Biriktirme, güncellemenin gerektirdiği şekilde, bölüm sırasına göre çıktı garantisi vermesi dışında DMLRequestSort = true(bir sütun deposu endeksinin seri taraması bu garantiyi sağlayamaz) dışında, yararlı bir işlev gerçekleştirmez . Makaranın maliyetinin, özellikle güncellemedeki maliyetin (muhtemelen gerçekçi olmayan) düşmesiyle karşılaştırıldığında nispeten düşük olduğu düşünülmektedir.

Sorgu optimizasyonunda güncelleme operatörüne sipariş girişi gerekip gerekmediğine dair karar çok erken alınır. Bu kararda kullanılan sezgisel tarama asla belgelenmemiş, ancak deneme yanılma yoluyla tespit edilebilir. Herhangi bir delta mağazasının büyüklüğünün bu kararın bir girişi olduğu görülüyor. Bir kez yapıldıktan sonra, seçim sorgu derlemesi için kalıcıdır. Hiçbir USE PLANipucu başarılı olmaz: planın hedefi ya güncellemeye girdi emri verdi ya da yapamadı.

Kardinalite tahminini yapay olarak sınırlamadan bu sorgu için düşük maliyetli bir plan elde etmenin başka bir yolu vardır. Biriktirmeyi önlemek için yeterince düşük bir tahmin muhtemelen DMLRequestSort'un yanlış olmasına ve beklenen rasgele G / Ç nedeniyle çok yüksek bir tahmini plan maliyetine yol açmasına neden olur. Bir seçenek 2332 (DMLRequestSort = true) ile birlikte izleme bayrağı 8649'u (paralel plan) kullanmaktır:

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332, QUERYTRACEON 8649);

Bu, bölüm başına toplu iş modu paralel tarama ve bir sipariş koruma (birleştirme) Toplama Akışı değişimini kullanan bir planla sonuçlanır:

Sıralı Sil

Donanımınızdaki bölüm siparişlerinin çalışma zamanı etkinliğine bağlı olarak bu, üçünün en iyisini yapabilir. Bununla birlikte, büyük değişiklikler sütun deposunda harika bir fikir değildir, bu nedenle bölüm değiştirme fikri neredeyse kesinlikle daha iyidir. Uzun derleme süreleri ile başa çıkabiliyorsanız ve sık sık planlanan seçeneklerle bölümlenmiş nesnelerle sıkça karşılaşabilirsiniz - özellikle bölüm sayısı büyük olduğunda.

Pek çok, nispeten yeni özelliklerin, özellikle de sınırlarının yakınında olması, kötü uygulama planları elde etmek için harika bir yoldur. Optimize edici desteğinin derinliği zamanla düzelme eğilimindedir, ancak 15.000 sütun deposu bölümü kullanmak muhtemelen her zaman ilginç zamanlarda yaşayacağınız anlamına gelir.

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.