SQL Server neden hala sorguyu yürütürken bazı satırları döndürüyor?


33

"Çalıştır" tuşuna bastığımızda bazı satırları gösterdiği ve büyümeye devam ettiği, ancak sorgunun henüz bitmediği sorgular var. Ancak bazen, sorgunun sonuna kadar bekler.

Bu neden oluyor? Bunu kontrol etmenin bir yolu var mı?

Yanıtlar:


43

Cevap, her zamanki gibi (çoğu zaman), uygulama planındadır.

Bu satırları işlemeye başlamadan önce tüm satırların onlara ulaşmasını gerektiren bazı operatörler var, örneğin aşağı akışta geçmeleri, örneğin:

  • Hash Join (karma tabloyu oluştururken)
  • Karma Eşleşmesi
  • Sıralama (Karma Akış Ayrımı Dışında)

Buna bloke denir veya bu nedenle operatörleri durdurur ve giderler, ve optimizer verilerinizi bulmak için çok fazla veriyi işlemek zorunda kalacağını düşündüklerinde genellikle seçilirler.

Akışa başlayabilen veya bulunan tüm satırları derhal geçiren başka operatörler var.

  • İç içe geçmiş döngüler
  • Dizin destekli Birleştirme Birleşmeleri
  • Akış Agregaları

Sorgular derhal veri döndürmeye başladığında, ancak derhal bitmiyorsa, bu genellikle optimizer'ın daha düşük başlangıç ​​maliyeti olan operatörleri kullanarak hızlı bir şekilde bazı satırları bulmak ve döndürmek için bir plan seçtiğinin bir işaretidir.

Bu, sizin tarafınızdan veya optimize edici tarafından sunulan satır hedefleri nedeniyle olabilir.

Ayrıca, bir sebepten dolayı kötü bir plan seçildiyse de olabilir (SARGability eksikliği, parametre koklama, yetersiz istatistikler, vb.), Ancak bunun farkına varmak için daha fazla kazma gerekir.

Daha fazla bilgi için, Rob Farley'nin bloguna buradan göz atın.

Ve Paul White'ın sıradaki hedefleri burada , burada , burada ve burada .

Ayrıca, SSMS hakkında konuşuyorsanız, satırların yalnızca willy-nilly değil, tüm bir tampon doldurulduktan sonra ortaya çıktığını belirtmek gerekir.


14

Ne gözlemliyoruz anlıyorsa, bu Management Studio nasıl kılar satır ve nasıl SQL Server ile ilgisi yoktur döner sıralar. Aslında, genellikle SSMS'ye büyük sonuçlar döndürdüğünüzde ve bunları bir ızgarada göstermeye çalıştığınızda, SSMS devam edemez ve SQL Server uygulamanın daha fazla satır işlemesini beklemesine son verir. Bu durumda, SQL Server'da biriken ASYNC_NETWORK_IObeklemeleri göreceksiniz .

SSMS, ızgara çizebileceğinden daha hızlı metin çizebildiğinden, bunu Kılavuzdan ziyade Sonuçlara Metin Kullanarak kontrol edebilirsiniz, ancak bunun sütun sayısına ve ilgili veri türlerine bağlı olarak okunabilirliği etkileyebileceğini göreceksiniz. Her ikisi de, SSMS, çıktı tamponunun ne kadar dolu olduğuna bağlı olarak, bu bölmeye sonuçları gerçekten yazmaya karar verdiğinde etkilenir.

Eğer varsa birden ifadeleri ve mesajlar bölmesine çıkış sonuçlarını işlemek için tampon zorlamak istiyorum, tablolar arasında hile baskı bir az şey kullanabilirsiniz:

RAISERROR('', 0, 1) WITH NOWAIT;

Ancak, tüm çıktılar tek bir ifadeden geldiğinde SSMS'yi satırları daha hızlı hale getirmeye çalıştığınızda bu yardımcı olmaz.

Daha doğrudan, SSMS'de kaç tane sonuç verdiğinizi sınırlayarak kontrol edebilirsiniz. İnsanların bir milyon satırlık şebekeye dönmesinin ne kadar süreceği konusunda şikayetçi olduklarını sık sık görüyorum. Yeryüzünde ne SSMS şebekesinde bir milyon satır ile yapacak, hiçbir fikrim yok.

OPTION (FAST 100)Bu ilk 100 sırayı almak için en iyi duruma getirecek bazı hackler var (ya da dış yoksa 100 sıra ORDER BY), ancak bu, geri kalan sıralar ve daha fazlası için bir plan için daha yavaş geri alma pahasına gelebilir. Genel olarak verimsiz, bu yüzden gerçekten bir seçenek gitmek IMHO değil.


1

Sorunuz kendi başına SQLServer ile ilgili değil:

  • SQL Server
  • İstemci uygulaması olarak SSMS

Bunu kontrol etmenin bir yolu var mı?

Kısa cevap :

  1. Deneyin sqlcmdyerine ssmsya sqlcmdait biçemssms
  2. Bağlantı ve oturum ayarlarınızı kontrol edin

Uzun cevap :

Tabii ki! Ama tek - prob

  1. Sorgunuzu ssms içinde -mode ile sqlcmdveya sqlcmdiçinde çalıştırın.
  2. Ağın rolünü dışlamak istiyorsanız - sorgunuzu Paylaşılan Bellek bağlantısına sahip sunucuda çalıştırın.
  3. Eğer sorgu performansı Paylaşımlı Hafıza bağlantısında bile tatmin edici değilse - yürütme planlarınızı analiz edin. Sorgu ağ üzerinden kötü performans gösteriyorsa - yardım için ağ ağ yöneticinizi arayın. Sorgunuz yalnızca SSMS’de kötü performans gösteriyorsa - daha fazlasını okuyun.
  4. Şimdi sorunların müşteri tarafında olduğundan eminiz (bu durumda ssms). SSMS'deki bağlantı ve oturum ayarlarına bakın. Ssms arayüzüne inanmayın ve SQL Profiler ile kontrol edin: bağlantınızı bulun spidve oturum ayarlarının tam listesini alın. sqlcmdOturum ayarları ile karşılaştırın . Hiçbir şey sqlcmdtıklamazsa , tüm oturum ayarlarını profilleyiciden sorgu betiğinize kopyalayın, mod içinde yürütün ve ayarları aşamalı olarak değiştirerek suçluunuzu bulun.

İyi şanslar!


-2

Sp_BlitzErik'in yanıtına eklemek için, NOT IN ()bir alt seçim ile a kullanarak örneği alın . Bir öğenin iç içe geçmiş sorgunun sonucu olup olmadığını belirlemek için, sonucun tamamını almak (genellikle) gereklidir.

Dolayısıyla, bu tür sorguların performansını iyileştirmenin bir yolunun kolay bir yolu, onları tarafın LEFT OUTER JOINkoşulunun RIGHTnull olduğu durumlarla yeniden yazmaktır (onu tersine çevirebilirdiniz, elbette ama kim kullanır RIGHT OUTER JOINS?). Bu, sonuçların hemen geri dönmesini sağlar.


Sanmıyorum Eğer karşılaştırılan sütunlar null yapılamazsa, sonuçlar aynı olmalı ve planlar - genellikle - aynı, bir anti-eklemin 3 versiyonu için (NOT IN VAR DEĞİL, SOL KATILIR / NULL DEĞİL). Tüm sonucu almak için gerekli değildir.
ypercubeᵀᴹ

Eğer alt seçim, üretilen sorgunun NOT IN koşulunu kontrol etmeden önce tüm alt seçimi değerlendirmek için ihtiyaç duyduğu gerçekten karmaşık bir sorundursa WHERE t.x IN (<complex SELECT subquery>), eşdeğer LEFT JOIN LEFT JOIN (<complex SELECT subquery>) AS r ON r.x = t.x .... WHERE r.x IS NULL, sonra alt sorgu değerlendirilmeye istekli hale gelir (NOT ile aynı karmaşık plan Sürümünde).
ypercubeᵀᴹ

@ ypercubeᵀᴹ Geçmişte benim için çalıştı. Sorguların birkaç dakika sonra tekrar başladığını gördüm.
JimmyJames

@ ypercubeᵀᴹ Oracle'da basit bir örnek oluşturdum (üzgünüm şu anda SQLServer'a erişemiyorum) ve kesinlikle farklı açıklama planları vardı. Belki de anlamlı farklar değildi ama oldukça farklı görünüyorlar.
JimmyJames,

@JimmyJames: Eğer istikrarlı bir performans istiyorsanız ve bu tür "optimizasyonlar" SQLServer versiyonu için çok hassassa bu kolay bir yöntem değildir. Ve Oracle'a hitap ederken hata yapmayın (hangi sürüm?). Tarihsel olarak SQLServer tercih etti NOT EXISTSancak Oracle NOT INsorgularda. Ancak bugün plan jeneratörde hata olarak görülmesi gerekiyor
Alex Yu
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.