500.000 行以上を含むビューに SELECT クエリがあります。シンプルにしましょう。
SELECT * FROM dbo.Document WHERE MemberID = 578310
クエリは高速に実行され、~0s
私のニーズをより反映した一連の値で動作するように書き直してみましょう。
SELECT * FROM dbo.Document WHERE MemberID IN (578310)
これは同じ高速で、 ~0s
しかし今、一連の ID は可変である必要があります。次のように定義しましょう。
DECLARE @AuthorizedMembers TABLE
(
MemberID BIGINT NOT NULL PRIMARY KEY, --primary key
UNIQUE NONCLUSTERED (MemberID) -- and index, as if it could help...
);
INSERT INTO @AuthorizedMembers SELECT 578310
セットには同じ 1 つの値が含まれていますが、現在はテーブル変数です。このようなクエリのパフォーマンスは に低下し2s
、より複雑なクエリでは と同じくらい高く25s
なりますが、固定 ID では約 にとどまります~0s
。
SELECT *
FROM dbo.Document
WHERE MemberID IN (SELECT MemberID FROM @AuthorizedMembers)
は次と同じ悪いです:
SELECT *
FROM dbo.Document
WHERE EXISTS (SELECT MemberID
FROM @AuthorizedMembers
WHERE [@AuthorizedMembers].MemberID = Document.MemberID)
またはこれと同じくらい悪い:
SELECT *
FROM dbo.Document
INNER JOIN @AuthorizedMembers AS AM ON AM.MemberID = Document.MemberID
パフォーマンスは上記のすべてで同じであり、常に固定値のパフォーマンスよりもはるかに悪いです。
動的 SQL には簡単にヘルプが付属しているため、nvarchar のようなもの(id1,id2,id3)
を作成し、それを使用して固定クエリを作成すると、クエリ時間を維持できます~0s
。しかし、動的SQLの使用はできるだけ避けたいと思います。もしそうなら、値に関係なく、常に同じ文字列を維持したいと思います(パラメータを使用 - 上記の方法では許可されていません)。
値の固定配列に似たテーブル変数のパフォーマンスを得る方法、または実行ごとに異なる動的 SQL コードを作成しないようにする方法はありますか?
PS私は同じ結果でユーザー定義型で上記を試しました
編集: 次のように定義された一時テーブルの結果:
CREATE TABLE #AuthorizedMembers
(
MemberID BIGINT NOT NULL PRIMARY KEY
);
INSERT INTO #AuthorizedMembers SELECT 578310
実行時間を最大 3 倍改善しました。(13秒 -> 4秒)。これは、動的 SQL <1s よりもかなり高いです。