オプティマイザーはvarcharパラメーターのnull可能性について混乱しているようで、その理由がわかりません。私はSQLServer2008を使用しています。クエリされるすべての列にインデックスが付けられます。TDate列は、クラスター化されたパーティション索引です。FooValue列はインデックス付きで、null許容でない列です。
例:
CREATE PROCEDURE dbo.MyExample_sp @SDate DATETIME, @EDate DATETIME, @FooValue VARCHAR(50)
AS
SET NOCOUNT ON
--To avoid parameter spoofing / sniffing
DECLARE @sDate1 DATETIME, @eDate1 DATETIME
SET @sDate1 = @sDate
SET @eDate1 = @eDate
SELECT
fd.Col1,
fd.Col2,
fd.TDate,
fl.FooValue,
fd.AccountNum
FROM dbo.FooData fd
INNER JOIN dbo.FooLookup fl
ON fl.FL_ID = fd.FL_ID
WHERE fd.TDate >= @sDate1
AND fd.TDate < @eDate1
AND fl.FooValue = @FooValue
これをクエリとして実行すると、期待どおりに機能します。すべてのインデックスはシークであり、なりすましなどはありません。sprocを実行してこれを実行すると、20倍の時間がかかります-同じクエリ-同じパラメータ。ただし、次の変更(最後の行)を行うと、すべてが再び機能します。
CREATE PROCEDURE dbo.MyExample_sp @SDate DATETIME, @EDate DATETIME, @FooValue VARCHAR(50)
AS
SET NOCOUNT ON
--To avoid parameter spoofing / sniffing
DECLARE @sDate1, @eDate1
SET @sDate1 = @sDate
SET @eDate1 = @eDate
SELECT
fd.Col1,
fd.Col2,
fd.TDate,
fl.FooValue,
fd.AccountNum
FROM dbo.FooData fd
INNER JOIN dbo.FooLookup fl
ON fl.FL_ID = fd.FL_ID
WHERE fd.TDate >= @sDate1
AND fd.TDate < @eDate1
AND fl.FooValue = ISNULL(@FooValue, 'testthis')
オプティマイザがパラメータがnull許容かどうかについて混乱しているようですか?また、パラメータにデフォルト値を追加しても違いはありません。= isnull(@parameter、'some constant')を使用しない限り、sprocの実行にはまだ永遠にかかります
私はこれを理解できてうれしいです。しかし、なぜこれが起こっているのか、そして問題を解決するためのよりエレガントな方法があったのかどうかを理解したいと思います。