実行時に述語が決定されるクエリがあります。私の現在の設計に基づくと、クエリの戻り時間は最適ではありません。クエリは複雑ではなく、(Tuning Adviser を使用して) 必要なインデックスが配置されていることを確認しました。述語がハードコーディングされていれば、クエリが高速になる可能性があることを私は証明しました。
以下は、私が問題を抱えているクエリです。
次のクエリは、完了するまでに数分かかります
declare
@matchFN bit = 1 -- match on first name
,@matchLN bit = 1 -- match on last name
;with cteContact1 as (
select distinct
c.ContactID
,ltrim(rtrim(FirstName)) FN
,ltrim(rtrim(LastName)) LN
from
dbo.contact c
left outer join
dbo.ContactCertification cc on c.ContactID = cc.ContactID
)
,cteContact2 as (
select
c.ContactID
,ltrim(rtrim(FirstName)) FN
,ltrim(rtrim(LastName)) LN
from
dbo.contact c
left outer join
dbo.ContactCertification cc on c.ContactID = cc.ContactID
)
select distinct
*
from
cteContact1 c1
join
cteContact2 c2 on
c1.FN = case when @matchFN = 1 then c2.FN else c1.FN end
and
c1.LN = case when @matchLN = 1 then c2.LN else c1.LN end
ただし、最終クエリを次のように変更すると、クエリは 5 秒以内に完了します。
select distinct
*
from
cteContact1 c1
join
cteContact2 c2 on c1.FN = c2.FN and c1.LN = c2.LN
最終的に、両方のクエリは同じものになるはずですが、なぜパフォーマンスに劇的な違いがあるのでしょうか?