許容時間内に実行されるクエリがありますが、そこから可能な限り最高のパフォーマンスを絞り出したいです。
私が改善しようとしている操作は、ノード17からのプランの右側にある「インデックスシーク」です。
適切なインデックスを追加しましたが、その操作に対して得られる推定値は、想定される値の半分です。
インデックスを変更し、一時テーブルを追加してクエリを書き直すことを探しましたが、適切な見積もりを得るためにこれ以上単純化することはできませんでした。
他に私が試すことができるものについて誰か提案がありますか?
更新:
質問の最初のバージョンは多くの混乱を引き起こしたと感じているので、いくつかの説明とともに元のコードを追加します。
create procedure [dbo].[someProcedure] @asType int, @customAttrValIds idlist readonly
as
begin
set nocount on;
declare @dist_ca_id int;
select *
into #temp
from @customAttrValIds
where id is not null;
select @dist_ca_id = count(distinct CustomAttrID)
from CustomAttributeValues c
inner join #temp a on c.Id = a.id;
select a.Id
, a.AssortmentId
from Assortments a
inner join AssortmentCustomAttributeValues acav
on a.Id = acav.Assortment_Id
inner join CustomAttributeValues cav
on cav.Id = acav.CustomAttributeValue_Id
where a.AssortmentType = @asType
and acav.CustomAttributeValue_Id in (select id from #temp)
group by a.AssortmentId
, a.Id
having count(distinct cav.CustomAttrID) = @dist_ca_id
option(recompile);
end
回答:
pasteThePlanリンクの最初の名前が奇妙なのはなぜですか?
回答:SQL Sentry Plan Explorerの匿名化プランを使用したためです。
なんで
OPTION RECOMPILE
?回答:パラメータスニッフィングを回避するために再コンパイルする余裕があるためです(データが歪んでいる/歪んでいる可能性があります)。私はテストしましたが、オプティマイザーが使用中に生成するプランに満足してい
OPTION RECOMPILE
ます。WITH SCHEMABINDING
?回答:私は本当にそれを避けたいので、インデックス付きビューがある場合にのみ使用します。とにかく、これはシステム関数(
COUNT()
)なので、SCHEMABINDING
ここでは使いません。
考えられるその他の質問への回答:
なぜ使用するの
INSERT INTO #temp FROM @customAttrributeValues
ですか?回答:クエリにプラグインされた変数を使用する場合、変数の操作から生じる推定値は常に1であることに気づき、今ではわかっているため、データを一時テーブルに入れてテストし、推定値が実際の行と等しいことをテストしました。
なぜ使用したの
and acav.CustomAttributeValue_Id in (select id from #temp)
ですか?回答:#tempでJOINに置き換えることもできましたが、開発者は非常に混乱し、
IN
オプションを提供しました。交換してもどちらにせよ違いがあるとは思いませんが、これで問題はありません。
select id from @customAttrValIds
代わりにを使用し、変数と#temp(実際select id from #temp
の行数に一致した)の行数の推定値を使用した場合、実際の実行計画を推定値で調べました。だから私はに置き換えました。そして、I DOは、彼らがTBL変数を使用した場合、そのための推定値は常に1と、彼らは一時テーブルを使用することになり、より良い推定値を得るための改善としてになるという(ブレントOまたはアーロン・ベルトランから)話を覚えています。1
3
@
#
#temp
作成と使用はパフォーマンスの問題であり、ゲインの問題ではないと思います。インデックス化されていないテーブルに保存して、一度だけ使用するようにします。完全に削除してみてください(そしておそらくそれin (select id from #temp)
をexists
サブクエリに変更してください。