カバリングインデックスを介してインデックス付きビューから結果を返すストアドプロシージャがあります。通常、高速で実行されます(約10ミリ秒)。場合によっては最大8秒で実行されることもあります。
ランダム実行の例を次に示します(注:これは遅いものではありませんが、渡される値を除いてクエリテキストは同じです)。
_declare @p2 dbo.IdentityType
insert into @p2 values(5710955)
insert into @p2 values(5710896)
insert into @p2 values(5710678)
insert into @p2 values(5710871)
insert into @p2 values(5711103)
insert into @p2 values(6215197)
insert into @p2 values(5710780)
exec ListingSearch_ByLocationAndStatus @statusType=1,@locationIds=@p2
_
SPROCは次のとおりです。
_ALTER PROCEDURE [dbo].[ListingSearch_ByLocationAndStatus]
@LocationIds IdentityType READONLY,
@StatusType TINYINT
AS
BEGIN
SET NOCOUNT ON;
SELECT -- lots of fields
FROM [dbo].[ListingSearchView][a] WITH (NOEXPAND)
INNER JOIN @LocationIds [b] ON [a].[LocationId] = [b].[Id]
WHERE [a].[StatusType] = @statusType
OPTION (RECOMPILE);
_
(注:最近、いくつかのアドバイスの後にOPTION (RECOMPILE)
ヒントを追加しましたが、役に立ちませんでした。
これがカバーするインデックスです(注:ビューにはListingId
にもクラスター化インデックスがあり、これは一意です)
_CREATE NONCLUSTERED INDEX [IX_ListingSearchView_ForAPI] ON [dbo].[ListingSearchView]
(
[LocationId] ASC,
[StatusType] ASC
)
INCLUDE ( -- all the fields in the query) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
_
Showplan XML統計を使用して、プロファイラートレースを配置しました。
私が期待するとおりに見え、クエリが高速の場合は同じ計画です。
これが役立つ場合のビュー/バッキングテーブルの完全なスキーマは次のとおりです。 https://Pastebin.com/wh1sRcbQ
ノート:
WITH OPTION (RECOMPILE);
ヒントを追加します(機能しなかったため、パラメーターをスニッフィングできませんか?)次に試してみたいアイデアはありますか?
ありがとう
OPTION (RECOMPILE)
を使用することが、パラメーターの盗聴の可能性を排除する効果的な方法であるとは本当に思いません。
パラメータスニッフィングは、SQLが特定のクエリについて混乱し、新しいパラメータを検出したためにSQLが新しいと考えるときに発生します。新しい実行プランを生成するために余分な時間がかかるため、処理が遅くなります。
そのオプションが行うことは、SQLに毎回新しいプランを強制的に生成させることですが、これはほとんど同じことです。代わりに、このヒントを使用してデフォルトパラメータを追加することを検討してください。
OPTION(OPTIMIZE FOR(@LocationIds='xx',@StatusType='xx'))
デフォルトのパラメータを選択するときは、統計的に代表的なセットを使用してください。
これにより、毎回同じプランが使用され、パラメータの盗聴の可能性がなくなります。それを行って、それが役に立たなかったと判断したら、おそらくパラメータの盗聴を可能性として無視しても安全です。
おそらく順序を強制しようとするので、おそらく常に小さなテーブル(変数)から始めます。でもそれはビューでトリッキーです...
SELECT -- lots of fields
FROM @LocationIds [b] WITH (NOEXPAND)
INNER JOIN [dbo].[ListingSearchView][a] WITH (NOEXPAND)
ON [a].[LocationId] = [b].[Id]
WHERE [a].[StatusType] = @statusType
OPTION (FORCE ORDER);
または、それが一般にテーブル変数をビューに結合する方法である場合は、ループ結合を強制できます。これも順序を強制します...
SELECT -- lots of fields
FROM @LocationIds [b] WITH (NOEXPAND)
INNER LOOP JOIN [dbo].[ListingSearchView][a] WITH (NOEXPAND)
ON [a].[LocationId] = [b].[Id]
WHERE [a].[StatusType] = @statusType
--leaving this here so you don't get an annoying warning
OPTION (FORCE ORDER);