Farklı makara türlerini seçerek hangi maliyet faktörleri optimize ediciye gider?


15

Spoolum

SQL Server'da birkaç tür makara vardır. Ben ilgilendiğimi ikisidir Tablo biriktirme ler ve Dizin bobinler , modifikasyon sorguları dışında .

Yalnızca İç İçe Döngüler birleşiminin iç tarafındaki salt okunur sorgular, G / Ç'yi azaltmak ve sorgu performansını iyileştirmek için bir Tablo veya Dizin biriktirme kullanabilir. Bu makaralar Eager veya Lazy olabilir . Tıpkı senin ve benim gibi.

Sorularım:

  • Tablo ve Dizin Biriktirme seçimine hangi faktörler girer?
  • Hangi faktörler Eager ve Lazy Spools arasında seçim yapar

Yanıtlar:


12

Bu biraz geniş ama bence Gerçek Soruyu anlıyorum ve buna göre cevap vereceğim. Sadece tablo vs dizin biriktirme hakkında konuşacağız. Orada tablo ve dizin makaralar arasında bir seçim olarak görmek oldukça doğru olduğunu düşünmüyorum. Bildiğiniz gibi, tek bir alt ağaçta bir dizin biriktirme, bir tablo biriktirme veya hem bir dizin biriktirme hem de bir tablo biriktirme elde etmek mümkündür. Aşağıdaki koşullarda bir dizin biriktirme aldığınızı söylemek genellikle doğru olduğuna inanıyorum:

  1. Sorgu iyileştiricinin bir birleştirmeyi bir uygulamaya dönüştürmek için bir nedeni var
  2. Sorgu iyileştirici, gerçekte uygulamaya dönüştürmeyi gerçekleştirir
  3. Sorgu iyileştirici, bir dizin biriktirme eklemek için kuralı kullanır (en azından dizin biriktirmenin kullanımı güvenli olmalıdır)
  4. İndeks makaralı plan seçilir

Bunların çoğunu basit demolarla görebilirsiniz. Bir çift yığın oluşturarak başlayın:

DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_901;
CREATE TABLE dbo.X_10000_VARCHAR_901 (ID VARCHAR(901) NOT NULL);

INSERT INTO dbo.X_10000_VARCHAR_901 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;


DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_800;
CREATE TABLE dbo.X_10000_VARCHAR_800 (ID VARCHAR(800) NOT NULL);

INSERT INTO dbo.X_10000_VARCHAR_800 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

İlk sorgu için aranacak bir şey yok:

SELECT *
FROM dbo.X_10000_VARCHAR_901 a
CROSS JOIN dbo.X_10000_VARCHAR_901 b
OPTION (MAXDOP 1);

Dolayısıyla, optimizatörün birleştirmeyi bir uygulamaya dönüştürmesi için hiçbir neden yoktur. Maliyet nedeniyle bir masa makarası ile sonuçlanırsınız. Bu sorgu ilk testi başarısız olur.

resim açıklamasını buraya girin

Bir sonraki sorgu için, optimize edicinin bir uygulamayı düşünmek için bir nedeni olmasını beklemek adil olacaktır:

SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID = b.ID 
OPTION (LOOP JOIN, MAXDOP 1);

Ancak bunun amacı yoktur:

resim açıklamasını buraya girin

Bu sorgu ikinci sınamada başarısız olur. Tam bir açıklama burada . En alakalı bölümden alıntı:

Optimize edici, bir uygulamayı etkinleştirmek için anında bir dizin oluşturmayı düşünmez; daha ziyade olaylar dizisi genellikle tersidir: iyi bir dizin olduğu için uygulanacak dönüşüm.

Optimize edicinin bir uygulamayı düşünmesini teşvik etmek için sorguyu yeniden yazabilirim:

SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID >= b.ID AND a.ID <= b.ID
OPTION (MAXDOP 1);

Ancak hala dizin biriktirme yok:

resim açıklamasını buraya girin

Bu sorgu üçüncü sınamada başarısız olur. SQL Server 2014'te, 900 baytlık bir dizin anahtarı uzunluk sınırı vardı. Bu, SQL Server 2016'da genişletildi, ancak yalnızca kümelenmemiş dizinler için. Bir biriktirme dizini kümelenmiş bir dizindir, bu nedenle sınır 900 baytta kalır . Her durumda, dizin biriktirme kuralı, sorgu yürütme sırasında hataya neden olabileceğinden uygulanamaz.

Veri türü uzunluğunu 800'e düşürmek, sonunda bir dizin makarası ile bir plan sağlar:

resim açıklamasını buraya girin

Endeks biriktirme planının, şaşırtıcı olmayan bir şekilde, biriktirme içermeyen bir plandan çok daha ucuza maliyeti vardır: 89.7603 birim vs 598.832 birim. Belgesiz QUERYRULEOFF BuildSpoolsorgu ipucuyla farkı görebilirsiniz :

resim açıklamasını buraya girin

Bu tam bir cevap değil, ama umarım aradığınız şeylerden bazılarıdır.

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.