SQL Server 2012'de neden boş sonuç ile sorgu hatası ayarlanmış?


31

Aşağıdaki sorguları MS SQL Server 2012'de çalıştırırken, ikinci sorgu başarısız olur, ancak ilk değil. Ayrıca, cümlecik olmadan çalıştırıldığında her iki sorgu da başarısız olur. Her ikisinin de boş sonuç kümeleri olması gerektiğinden ikisinin de başarısız olacağı bir zararım var. Herhangi bir yardım / içgörü takdir edilmektedir.

create table #temp
(id     int primary key)

create table #temp2
(id     int)

select 1/0
from #temp
where id = 1

select 1/0
from #temp2
where id = 1

Yanıtlar:


39

Yürütme planlarına ilk bakış, ifadenin 1/0Hesaplama Skaler işleçlerinde tanımlandığını gösterir :

Grafik planlar

Şimdi, yürütme planları en solda çalışmaya başlasa da, yinelemeli arama Openve GetRowalt yineleyicilere sonuçları döndürme yöntemleri, SQL Server 2005 ve sonraki sürümleri, ifadelerin genellikle bir Hesaplama Ölçeği tarafından tanımlanmasını , böylece bir sonraki aşamaya kadar ertelenmesi gereken bir optimizasyon içerir. işlem sonucu gerektirir :

SET STATISTICS tarafından oluşturulan Showplans'ta görünen Hesaplama işleçleri XML, RunTimeInformation öğesini içermeyebilir.  SQL Server Management Studio'da Gerçek Yürütme Planını Dahil Et seçeneği seçildiğinde, Grafik Gösterilerinde, Gerçek Satırlar, Gerçek Rebinds ve Gerçek Rewinds Özellikler penceresinden bulunmayabilir.  Bu gerçekleştiğinde, bu operatörler derlenmiş sorgu planında kullanılmasına rağmen çalışmalarının çalışma zamanı sorgu planında diğer operatörler tarafından yapıldığı anlamına gelir.  Ayrıca, SET STATISTICS PROFILE tarafından oluşturulan Showplan çıktısındaki çalıştırma sayısının, SET STATISTICS XML tarafından oluşturulan Showplans öğelerinde yeniden yapılanma ve geri sarma toplamına eşdeğer olduğunu unutmayın.  Gönderen: MSDN Çevrimiçi Kitapları

Bu durumda, ifade sonucu yalnızca satırı müşteriye geri gönderilmek üzere toplarken gereklidir (ki bu yeşil SELECTsimgede gerçekleşeceğini düşünebilirsiniz ). Bu mantıkla, ertelenmiş değerlendirme, ifadenin asla değerlendirilmediği anlamına gelir, çünkü hiçbir plan bir geri dönüş satırı oluşturmaz. Bu noktaya biraz emek vermek için, ne Kümelenmiş Dizin Arayışı ne de Tablo Taraması bir satır döndürür, böylece müşteriye geri dönmek için bir araya getirilecek satır yoktur.

Ancak, bazı ifadelerin çalışma zamanı sabitleri olarak tanımlanabildiği ve sorgu yürütme başlamadan önce bir kez değerlendirildiği ayrı bir optimizasyon vardır . Bu durumda, bunun gerçekleştiğine dair bir gösterge showplan XML'de bulunabilir (solda Kümelenmiş Dizin Ara planı, sağdaki Tablo Tarama planı):

Showplan XML

Bu blog yazısında altta yatan mekanizmalar ve performanslarını nasıl etkileyebilecekleri hakkında daha fazla yazdım . Burada verilen bilgileri kullanarak ilk sorguyu değiştirebiliriz, böylece her iki ifade de yürütme başlamadan önce değerlendirilir ve önbelleğe alınır:

select 1/0 * CONVERT(integer, @@DBTS)
from #temp
where id = 1

select 1/0
from #temp2
where id = 1

Şimdi, ilk plan aynı zamanda sabit bir ifade referansı içeriyor ve her iki sorgu da hata mesajını veriyor. İlk sorgu için XML içerir:

Sabit İfade

Daha fazla bilgi: Skaler, İfadeler ve Performansı Hesapla


21

Ben akıllıca tahmin edeceğim (ve bu süreçte muhtemelen gerçekten ayrıntılı bir cevap verebilecek bir SQL Server gurusu çekecektir).

İlk sorgu yürütme olarak şöyle yaklaşır:

  1. Birincil anahtar dizinini tara
  2. Sorgu için gereken veri tablosundaki değerleri arayın

Bu yolu seçer, çünkü wherebirincil anahtarda bir cümlecik vardır. Asla ikinci adıma geçmez, bu yüzden sorgu başarısız olmaz.

İkincisi, çalıştırılacak birincil anahtara sahip olmadığı için sorguyu şu şekilde görür:

  1. Verilerin tam tablo taramasını yapın ve gerekli değerleri alın

Bu değerlerden biri 1/0soruna neden oluyor.

Bu, sorguyu optimize eden bir SQL Server örneğidir. Çoğunlukla, bu iyi bir şey. SQL Server, koşulları selecttablodan tarama işlemine taşıyacaktır . Bu genellikle sorgunun değerlendirilmesindeki adımları kaydeder.

Ancak, bu optimizasyon onaylanmamış iyi bir şey değildir. Aslında, yan tümce değerlendirilmeden önce değerlendirilir diyor SQL Server belgelerin kendisi ihlal görünüyor . Bunun ne anlama geldiğiyle ilgili bazı yanlış açıklamalar yapabilirler. Yine de çoğu insan için mantıksal olarak işlemden önce (diğer şeylerin yanı sıra) " kullanıcıya geri dönmeyen satırlarda -clause hataları üretmeyin" anlamına gelir .whereselectwhereselectselect


1
+1 haklıysanız ipucu yok, ancak en iyi cevabı verdiğim tek fark birincil anahtar.

1
@ GordonLinoff Paul Randal, Twitter üzerinden sadece cevabınızı aldığınızı doğruladı.
SchmitzIT

4
@Still, asıl yürütme sırası, ancak farklı olmasına rağmen, böyle hata mesajlarına yol açmamalıdır.
ypercubeᵀᴹ

7
@ypercube Erland Sommarskog sizinle hemfikirdir (Connect item)
Paul White, GoFundMonica

2
İşaretçi için teşekkür ederim - Giriş yaptım ve isteği reddettim.
Gordon Linoff
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.