Toplanmışlar için dizine alınmış görünümler kullanmak - gerçek olamayacak kadar iyi?


28

Oldukça büyük bir kayıt sayısına (10-20 milyon satır) sahip bir veri ambarımız var ve genellikle belirli tarihler arasındaki kayıtları sayan veya belirli bayraklara sahip kayıtları sayan sorguları çalıştırıyoruz.

SELECT
    f.IsFoo,
    COUNT(*) AS WidgetCount
FROM Widgets AS w
JOIN Flags AS f
    ON f.FlagId = w.FlagId
WHERE w.Date >= @startDate
GROUP BY f.IsFoo

Performans korkunç değil, ama nispeten yavaş olabilir (soğuk bir önbellekte 10 saniye).

Son zamanlarda GROUP BY, indekslenmiş görünümlerde kullanabileceğimi keşfettim ve bu yüzden aşağıdakine benzer bir şey denedim

CREATE VIEW TestView
WITH SCHEMABINDING
AS
    SELECT
        Date,
        FlagId,
        COUNT_BIG(*) AS WidgetCount
    FROM Widgets
    GROUP BY Date, FlagId;
GO

CREATE UNIQUE CLUSTERED INDEX PK_TestView ON TestView
(
    Date,
    FlagId
);

Sonuç olarak, ilk sorgunun performansı şimdi <100ms ve sonuçta ortaya çıkan görünüm & dizin <100k (satır sayımız büyük olmasına rağmen, tarih ve bayrak kimlikleri aralığı bu görünümün yalnızca 1000-2000 satır içerdiği anlamına gelir).

Belki de bunun Widget tablosuna yazma işleminin performansını azaltacağını düşündüm, ama hayır - bu tablodaki eklerin ve güncellemelerin performansı söyleyebileceğim kadar etkilenmedi (artı, bu tablonun nadiren güncellenmesi Neyse)

Bana göre bu gerçek olamayacak kadar iyi görünüyor - öyle mi? Dizinli görünümleri bu şekilde kullanırken neye dikkat etmeliyim?


2
Senaryolarınızı gerçekten geçerli SQL için yeniden yazabilir misiniz? Senaryonuzun olduğuna inanıyorum ki sen SELECTve CREATE VIEWsenaryolar yanlış CREATE INDEX.
Mark Sinkinson

2
@MarkSinkinson Özür dileriz, hayali tablolar için geçerli bir SQL yazmaya çalışmanın zor olduğu ortaya çıktı
Justin

'Gerçek olamayacak kadar iyi' kısmı, MAX, kendinden veya dış birleştirmeleri içeren veya daha başka bir görünüme referans veren bir görünümü indekslemek gibi daha gelişmiş görünümler istediğimde geldi - hepsi en azından SQL Server'da değildi. izin verilen docs.microsoft.com/en-us/sql/relational-databases/views/… . Bu yüzden her zaman aşırı hırslı olmaya başladım ve sonra bir şeyleri geri ölçeklendirmek zorunda kaldım. Ancak daha basit toplamalar için gerçekten harikalar - SUM bile destekleniyor.
Simon_Weaver

Yanıtlar:


29

Sizin de belirttiğiniz gibi, görünümün kendisi yalnızca az sayıda satırı oluşturuyor - tüm tabloyu güncelleseniz bile , görünümü güncellemeyle ilgili ek G / Ç ihmal edilebilir. Muhtemelen manzarayı yaratırken hissedeceğiniz en büyük acıyı çoktan hissettiniz. Bir sonraki en yakını, görünümde yeni satırlar gerektiren bir grup yeni kimliğe sahip taban tablosuna bir gazillion satırı eklerseniz olacak.

Bu gerçek olamayacak kadar iyi değil. Dizinli görünümleri tam olarak nasıl kullanılmaları gerektiği - veya en etkili yollardan en az biri: yazma zamanında gelecekteki sorgu toplamalarını ödemek için kullanıyorsunuz. Bu, sonuç kaynağından çok daha küçük olduğunda ve elbette, toplamaların, temel verilerden daha sık talep edildiğinde (elbette DW'da OLTP'den daha yaygın) istendiğinde en iyi şekilde çalışır.

Maalesef çoğu kişi bir görünümü endekslemenin sihir olduğunu düşünüyor - bir indeks tüm görünümleri daha verimli hale getirmiyor, özellikle de tablolara katılan ve / veya kaynak ile aynı sayıda satır üreten (hatta çoğaltan) görünümler. Bu durumlarda, görünümdeki G / Ç, yalnızca aynı veya daha fazla satır olduğu için değil, aynı zamanda daha fazla sütunu depoladığı ve ürettiği için orijinal sorgudan aynı veya daha da kötüdür. Bu nedenle, bunları önceden gerçekleştirme herhangi bir kazanç sağlamaz, çünkü - SSD'lerde bile - G / Ç, ağ ve müşteri işleme / oluşturma, müşteriye büyük sonuçların gönderilmesinde hala temel tıkanıklıklar olmaya devam etmektedir. Çalışma zamanında katılımdan kaçınarak elde ettiğiniz tasarruflar, halen kullanmakta olduğunuz diğer tüm kaynaklara kıyasla ölçülemez.

Kümelenmemiş dizinler gibi, fazla yapmamaya dikkat edin. Bir tabloya 10 farklı dizine eklenmiş görünüm eklerseniz, özellikle gruplama sütunları kümeleme anahtarı (içinde) değilse, iş yükünüzün yazma bölümüne daha fazla etki göreceksiniz.

Tanrım, bu konuyla ilgili blog yazıyordum.


19

Aarons cevapları bu soruyu iyi ele aldı. Eklenecek iki şey:

  1. Toplama dizine alınmış görünümler, satırlar arası çekişmelere ve kilitlenmelere yol açabilir. Normal olarak, iki kesici uç kilitlenmez (kilit yükseltme veya kilit karmaşası gibi oldukça nadir durumlar hariç). Ancak her iki kesici uç da aynı gruba hitap ederse, tartışacaklar. Aynı nokta kilitleri alan herhangi bir şeyi (DML, kilit ipuçlarını) gösterir.
  2. Toplanmayan dizine alınmış görünümler de yararlı olabilir. Birden çok tablodaki sütunlarda dizin oluşturmanıza izin verir. Bu şekilde bir tablo üzerinde etkili bir şekilde filtre uygulayabilir ve birleştirilmiş tablodaki bir sütuna göre sipariş verebilirsiniz. Bu kalıp tam masa birleşimini sabit zaman aralıklı sorgulara dönüştürebilir.

Hem toplama hem de görüşlere aşırı yararı ile katıldım.

Tüm kullanım durumunuzda mükemmel bir durum gibi görünüyor. İndekslenmiş görüşler, yeterince kullanılmayan bir tekniktir.

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.