SQL Server 2012'de iki sorguyu karşılaştırma


14

Ben hedefi tüm kullanmaktır SQL Server 2012'de iki sorgu kıyaslıyorum ilgili en iyi sorgu seçerken sorgu en iyi duruma gelen bilgilerle. Her iki sorgu da aynı sonuçları üretir; tüm müşteriler için maksimum sipariş.

Tampon havuzunun temizlenmesi, her sorgu FREEPROCCACHE ve DROPCLEANBUFFERS ile yürütülmeden önce yapıldı

Aşağıda verilen bilgileri kullanarak, hangi sorgu daha iyi bir seçimdir?

-- Query 1 - return the maximum order id for a customer
SELECT orderid, custid
FROM Sales.Orders AS O1
WHERE orderid = (SELECT MAX(O2.orderid)
                 FROM Sales.Orders AS O2
                 WHERE O2.custid = O1.custid);


-- Query 2 - return the maximum order id for a customer
SELECT MAX(orderid), custid
FROM Sales.Orders AS O1
group by custid
order by custid

İSTATİSTİK ZAMAN

Sorgu 1 İSTATİSTİK ZAMANI: CPU süresi = 0 ms, geçen süre = 24 ms

Sorgu 2 İSTATİSTİK ZAMANI: CPU süresi = 0 ms, geçen süre = 23 ms

İSTATİSTİK IO

Sorgu 1 İSTATİSTİK IO: Tablo 'Siparişler'. Tarama sayısı 1, mantıksal okumalar 5, fiziksel okumalar 2, ileri okumalar 0, lob mantıksal okumalar 0, lob fiziksel okumalar 0, lob okuma öncesinde okumalar 0.

Sorgu 2 İSTATİSTİK IO: Tablo 'Siparişler'. Tarama sayısı 1, mantıksal okumalar 4, fiziksel okumalar 1, okuma öncesi okumalar 8, lob mantıksal okumalar 0, lob fiziksel okumalar 0, lob okuma öncesinde okumalar 0.

Uygulama Planları

resim açıklamasını buraya girin

SEÇ özellikler Sorgu 1

resim açıklamasını buraya girin

SEÇ özellikleri Sorgu 2

resim açıklamasını buraya girin

Sonuç:

Sorgu 1

  1. Parti maliyeti 48%
  2. Mantıksal Okumalar 5
  3. Fiziksel Okumalar 2
  4. İleri Okuma: 0
  5. CPU Süresi: 0 ms
  6. Geçen Süre 24ms
  7. Tahmini alt ağaç maliyeti: 0.0050276
  8. CompileCPU: 2
  9. Derleme Bellek: 384
  10. Derleme Zamanı: 2

Sorgu 2

  1. Parti maliyeti 52%
  2. Mantıksal Okumalar 4
  3. Fiziksel Okumalar 1
  4. İleri Okumalar: 8
  5. CPU Süresi 0
  6. Geçen Süre 23ms
  7. Tahmini alt ağaç maliyeti: 0.0054782
  8. CompileCPU: 0
  9. Derleme Bellek: 192
  10. Derleme Zamanı: 0

Şahsen, Sorgu 2, grafik planına göre daha yüksek bir toplu maliyete sahip olsa da, Sorgu 1'den daha etkili olduğunu düşünüyorum. düşürün. okuma-okuma değerleri sorgu 2 için 8 ve sorgu 1 için 0'dır.

Güncelleme 12:03

Kümelenmiş Dizin tanımı

ALTER TABLE [Sales].[Orders] ADD  CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
(
    [orderid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

Kümelenmemiş Dizin idx_nc_custid

CREATE NONCLUSTERED INDEX [idx_nc_custid] ON [Sales].[Orders]
(
    [custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

Yorumlar uzun tartışmalar için değildir; bu görüşme sohbete taşındı .
Paul White 9

Yanıtlar:


10

Ayarlama ve seçenekleri ve planları gözden geçirme konusundaki dikkatli düşünmeye yaklaşımınızı seviyorum. Keşke daha fazla geliştirici bunu yapsaydı. Dikkat edilmesi gereken bir şey var - mantıksal okumalara bakarak her zaman çok sayıda satırla test edin, bu ufacık bir tablo. Bir örnek yük deneyin ve sorguyu yeniden çalıştırın. Küçük bir sorun - en üst sorgunuzda, bir sipariş istemiyorsunuz, alt sorgunuzda. Her birini siparişle karşılaştırmalı ve karşılaştırmalısınız.

Hızlı bir şekilde içinde 200.000 müşteri siparişi içeren bir SalesOrders tablosu oluşturdum - hala hayal gücünün genişlemesiyle değil. Ve her birinde ORDER BY ile sorguları çalıştırdı. Ben de biraz endekslerle oynadım.

OrderID üzerinde kümelenmiş dizin olmadan, yalnızca CustID üzerinde kümelenmemiş bir dizin İkinci sorgu daha iyi performans gösterdi. Özellikle sipariş dahil her biri tarafından. İlk sorguda ikinci sorgudan iki kat daha fazla okuma vardı ve sorgular arasında maliyet yüzdeleri% 67 /% 33 idi.

OrderID üzerinde kümelenmiş bir dizin ve yalnızca CustID üzerinde kümelenmemiş bir dizin ile Benzer bir hızda ve aynı sayıda okuma gerçekleştirdiler.

Bu yüzden satır sayısını artırmanızı ve biraz daha test yapmanızı öneririm. Ama sorularınızla ilgili son analizim -

Satırları artırdığınızda fark ettiğinizden daha benzer şekilde davrandıklarını görebilirsiniz, bu nedenle bu uyarıyı aklınızda tutun ve bu şekilde test edin.

Geri dönmek istediğiniz tek şey her Müşteri için maksimum OrderID ise ve OrderID ile en büyük OrderID olduğunu belirlemek istiyorsanız, bu ikisinin ikinci sorgusu zihnimden gitmek için en iyi yoldur - biraz daha basit ve alt ağaç maliyetine göre biraz daha pahalı olsa da, daha hızlı ve daha kolay bir şekilde deşifre edilebilir. Bir gün sonuç kümenize başka sütunlar eklemeyi düşünüyorsanız? Sonra ilk sorgu bunu yapmanızı sağlar.

Güncellendi: Sorunuz altındaki yorumlarınızdan biri:

Bu soruda en iyi sorguyu bulmanın, bunları karşılaştırmak için kullanılan teknikleri iyileştirmenin bir yolu olduğunu lütfen unutmayın.

Ancak, bu testi daha fazla veri ile yapmak için en iyi paket - her zaman üretim ve beklenen gelecekteki üretim ile tutarlı verilerinizin olmasını sağlar. Sorgu planları, tablolara daha fazla satır verdiğinizde veri aramaya başlar ve üretimde beklediğiniz dağıtımı tutmaya çalışır. Ve Order By veya not dahil gibi şeylere dikkat edin, burada sonunda korkunç bir fark yarattığını düşünmüyorum, ama yine de kazmaya değer.

Bu düzeyde ayrıntı ve veriyi karşılaştırma yaklaşımınız iyi. Alt ağaç maliyetleri çoğunlukla keyfi ve anlamsızdır, ancak yine de en azından düzenlemeler / değişiklikler arasında ve hatta sorgular arasında karşılaştırma yapmaya değer. Zaman istatistiklerine ve ES'ye bakmak, çalıştığınız verilerin boyutu ve ne yapmaya çalıştığınız için yerin dışında hissettiği her şeye bakarken oldukça önemlidir.


Tekrar merhaba, daha büyük miktarda veri kullanma hakkındaki puanlarınız için teşekkür ederiz. Birisi bunu ilk kez gündeme getirmedi. Son kez, sayfa bölünmelerinden olası parçalanmayı dikkate almaktı. 200.000 sıralı numunenizde parçalanmayı kontrol ettiniz mi?
Craig Efrein

200k sıralı küçük sıra örneğimde parçalanmaya odaklanmıyordum, hayır. Ama bunu yaptığım gibi olmazdı. Tablo oluşturdum, doldurdum ve sonra indeksler yaptım, Bu yüzden taze oluşturulmuş indekslerdi. Ve bu ana soru gibi görünen sorgu planlarına bakma yaklaşımını değiştirmeyecek. Veri hacmi, sorgu planlarına doğru bir şekilde bakıldığında büyük - gerçekten büyük -. Sık sık dev (1-10 satır) harika görünüyordu ve gerçek veriler ile eşya korkunç vakalar gördüm. Ancak yaklaşımınız iyi ve umarım bu bilgi ve yorumlardaki konuşma yardımcı olur
Mike Walsh

Custid'e göre gruplandırdığımızdan, custid değerlerini yeterince rasgele nasıl yaptınız? Okumalarımdan hatırladığım bir şey, farklı değerlerin önemi. Müşteri sadece az sayıda farklı müşteriye sahip olsaydı, akış toplamı için maliyet gerçekçi olmazdı.
Craig Efrein

Ben sadece 100 müşteri oluşturmak için RAND işlevini kullandım ve her sipariş kimliği rastgele bir atamak .. Hızlı bir kontrol yapıyordum. :)
Mike Walsh

Yardımın için teşekkürler Mike. Yine de son bir soru. 2012 yılında yürüttüğüm Yürütme Planındaki SELECT özellikleri ekranlarında sorumu verdiğim değerlere hangi değerlere dikkat ediyorsunuz?
Craig Efrein
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.