2016-03-24 10 views
0

WHERE NOT EXISTS kullanan aşağıdaki sorguyu iyileştirmenin mümkün olup olmadığını görmek istiyorum?INSERT deyiminden WHERE EXISTS OLMAYI iyileştirme

Başka bir tablodan, anahtarların geçici bir tabloda bulunduğu 500'lü gruplar halinde yeni bir kayıt eklemek istiyorum, ancak çalışıyorsa, performansını artırmak istiyorum.

WHILE 1 = 1 

BEGIN 

INSERT INTO newTable WITH (TABLOCK) 
     SELECT TOP(500) * 
     FROM srcTable src 
     WHERE NOT EXISTS (SELECT 1 FROM newTable WHERE pKey = src.pKey 
          AND src.pKey IN (SELECT pKey FROM #TempTable)) 

IF @@ROWCOUNT < 500 BREAK 
END 

Teşekkürler!

+2

. 500 satır çok küçüktür. 10k'nın hızlı tamamlamanın devrilme noktasında olacağını düşünürdüm ama çok fazla iterasyon yok. –

+0

#TempTable'da kaç tane satır var? – FLICKER

+0

#TempTable, 7072 kayıtlarına sahiptir – Billy

cevap

0

Her iki koşulu da not exists'a eklemek garip görünüyor. Yani düşünüyorum:

INSERT INTO newTable WITH (TABLOCK) 
    SELECT TOP(500) * 
    FROM srcTable src 
    WHERE NOT EXISTS (SELECT 1 FROM newTable nt WHERE nt.pKey = src.pKey) AND 
      NOT EXISTS (SELECT 1 FROM #TempTable tt WHERE src.pKey = t.pkey); 

Sonra bu sorgu için ben newTable(pkey) ve #TempTable(pkey) üzerine endeksler istemez.

Not: Bu mantığa sahip olduğumu düşünüyorum. İlişkili NOT EXISTS'daki ilişkisiz bir tabloya IN koymak biraz kafa karıştırıcıdır.

DÜZENLEME:

Hmmm. . . O mantık yanlış var ise, o zaman sadece ikinci koşuluyla EXISTS istiyorum: Ben toplu boyutunu artırarak başlayacaktı

INSERT INTO newTable WITH (TABLOCK) 
    SELECT TOP(500) * 
    FROM srcTable src 
    WHERE NOT EXISTS (SELECT 1 FROM newTable nt WHERE nt.pKey = src.pKey) AND 
      EXISTS (SELECT 1 FROM #TempTable tt WHERE src.pKey = t.pkey); 
+0

"Varolmayan" formun tersine, srcTable ve #TempTable arasında bir "iç birleştirme" yapmanın daha verimli olduğu herhangi bir koşul var mı? –

+0

@PhilipKelley. . . Var olmayan bir “içsel katılım” ile değiştirmenin bir yolunu düşünemiyorum. Bunu, sol dış birleştirmeyle değiştirebilirsiniz ve sanırım performans karşılaştırılabilir olurdu. En azından, her iki sürüm de ("left join" ve "değil"/"in") mevcut sorgudan daha iyi olurdu çünkü ilk daha iyi optimize edilirdi. –

+0

Bunu okuduğum şekilde, OP yalnızca #temp tablosunda kimliğin bulunduğu yerdeki ve yalnızca henüz kopyalanmadıysa newTable'daki verileri kopyalamak istiyor. Bu yüzden, #temp'de newTable'a katılın (yalnızca yasal hedefler alın) ve daha sonra yalnızca kopyalanmadıysa kopyalayın ("mevcut değil" ibaresiyle). –