2016-03-22 17 views
3

İki tablo var a, b, birincil anahtar onların dizini.Parametre neden SQL Server'da bir tablo taraması

Gereği

: kimin b.PKey boştur, a, b ait tüm kayıtları seçmek

@filter, başka herhangi bir özel ayırıcı tarafından @filter bölmek bulmak kayıtları filtresi içindedir.

Güncel Uygulama:

declare @filter nvarchar(max)= '' 

SELECT * 
FROM a 
JOIN b ON a.PKey = b.aPKey 
     AND (@filter = '' OR b.PKey IN (SELECT item FROM splitFunction(@filter)) 

Hep bir tablo I @filter='' kaldırırsanız sadece, o aramaya indeksine değişecek, masa b tarama neden olacaktır son açıklama and (@filter = '' or b.PKey in (select item from splitFunction(@filter)) bulundu.

Gereksinimi yerine getirmenin herhangi bir yolu var mı ve performansa zarar vermez mi?

+1

Lütfen bu http://stackoverflow.com/questions/31500/do-indexes-work-with-in-clause adresini ziyaret edin –

+0

@AbdulRasheed, teşekkürler, aynı sorun değil gibi görünüyor. Sorum şu: birleştirme koşulu '@filter = ''' bir tablo taramasına neden oluyor. Kaldırırsam, dizin kullanılacaktır. – BartMao

+2

İlgili: [Dinamik Arama Koşulları] (http://www.sommarskog.se/dyn-search-2008.html) –

cevap

1

sabitleri için, iyileştirici verilen değerler için istatistiklere dayalı iyi plan egzersiz yapabilirler.

Değişken kullandığınızda, parametrelendirmeyi zorlarsınız ve plan, çok çeşitli değerler için yeniden kullanılabilir olacak şekilde tasarlanacaktır. Dolayısıyla Optimizer tarama kullanır ve aramaz. Ben parametresine yerel değişken dönüştürdük saklı yordam gibi sorguda yerel değişkenleri kullanarak bu sorunu durdurmak üstesinden gelmek ve saklı yordam parametre olarak bu kullanmak için

create procedure p1 
@filter = '' 
as 
begin 
SELECT * 
FROM a 
JOIN b ON a.PKey = b.aPKey 
     AND (@filter = '' OR b.PKey IN (SELECT item FROM splitFunction(@filter)) 
option (recompile) 
end 

Bu, doğru planı verecektir.

+0

Evet, işe yarıyor! Ama yine de bundan şüphe duyuyorum, eğer bu optimizatörden kaynaklanıyorsa, bu ifadenin neden çalışmıyor? 'OPTIONSIZ (@Filtre = '')) – BartMao

+0

Option Option Option Optioner, bir yerel değişken ve @filter bir değişken olduğu için çalışmaz. Optimize etmenin neden çalışmadığının nedeni budur. Eğer saklı yordamda aynı kullanırsanız, – sam

+0

çalışacaktır, bu aslında saklı yordamda yaptım, işe yaramadı :(. Bir kez değiştirildi (yeniden derleme) ', yine çalışır. – BartMao

1

Özellikle bu durum için, ayrıca bu deneyebilirsiniz:

DECLARE @filter nvarchar(max)= '' 

IF @filter = '' 
BEGIN 
    SELECT * 
    FROM a 
    JOIN b ON a.PKey = b.aPKey 
END 
ELSE 
BEGIN 
    SELECT * 
    FROM a 
    JOIN b ON a.PKey = b.aPKey 
    WHERE b.PKey IN (SELECT item FROM splitFunction(@filter)) 
END 
+0

Evet, bu çalışır. Ama burada benim sorum açık bir şekilde açıklayabilecek bir örnektir. Birden fazla tablo ve birden fazla filtreniz varsa. Bu şekilde işe yaramaz gibi görünüyor. – BartMao

+0

Evet, birden fazla tablonuz varsa, bu en uygun çözümle sonuçlanmaz. Bu yüzden bu dava için özel olarak bahsettim. – AKS