T-SQLは、典型的な公開コンテキストでパフォーマンスをマージします
-
29-10-2019 - |
質問
「パブリッシャー」アプリケーションが、非常に複雑なビューを照会し、結果を非正規化ビューモデルテーブルにマージし、個別の挿入、更新、および削除操作を使用して、結果を非正規化ビューモデルテーブルにマージすることにより、基本的にビューモデルを最新の状態に保ちます。
SQL 2008にアップグレードしたので、SQL Mergeステートメントでこれらを更新するのに最適な時期だと思いました。ただし、クエリを書いた後、マージステートメントのサブツリーコストは1214.54です!古い方法では、挿入/更新/削除の合計はわずか0.104でした!!
まったく同じ操作を説明するより簡単な方法が非常に粗末であることを理解することはできません。おそらく、あなたは私ができない場所の私の方法の誤りを見ることができます。
テーブル上のいくつかの統計:190万行があり、それぞれの操作が挿入、更新、または100を超える削除をマージします。私のテストケースでは、影響を受けているのは1つだけです。
-- This table variable has the EXACT same structure as the published table
-- Yes, I've tried a temp table instead of a table variable, and it makes no difference
declare @tSource table
(
Key1 uniqueidentifier NOT NULL,
Key2 int NOT NULL,
Data1 datetime NOT NULL,
Data2 datetime,
Data3 varchar(255) NOT NULL,
PRIMARY KEY
(
Key1,
Key2
)
)
-- Fill the temp table with the desired current state of the view model, for
-- only those rows affected by @Key1. I'm not really concerned about the
-- performance of this. The result of this; it's already good. This results
-- in very few rows in the table var, in fact, only 1 in my test case
insert into @tSource
select *
from vw_Source_View with (nolock)
where Key1 = @Key1
-- Now it's time to merge @tSource into TargetTable
;MERGE TargetTable as T
USING tSource S
on S.Key1 = T.Key1 and S.Key2 = T.Key2
-- Only update if the Data columns do not match
WHEN MATCHED AND T.Data1 <> S.Data1 OR T.Data2 <> S.Data2 OR T.Data3 <> S.Data3 THEN
UPDATE SET
T.Data1 = S.Data1,
T.Data2 = S.Data2,
T.Data3 = S.Data3
-- Insert when missing in the target
WHEN NOT MATCHED BY TARGET THEN
INSERT (Key1, Key2, Data1, Data2, Data3)
VALUES (Key1, Key2, Data1, Data2, Data3)
-- Delete when missing in the source, being careful not to delete the REST
-- of the table by applying the T.Key1 = @id condition
WHEN NOT MATCHED BY SOURCE AND T.Key1 = @id THEN
DELETE
;
それでは、これはどのようにして1200のサブツリーコストになりますか?テーブル自体からのデータアクセスは非常に効率的であるようです。実際、マージのコストの87%は、チェーンの端近くの種類の操作によるものであると思われます。
マージ(0%)< - インデックスアップデート(12%)< - ソート(87%)< - (...)
そして、その種類には、0行に給餌します。 0行の87%がリソースの87%が必要なのですか?
アップデート
実際の(推定されていない)を投稿しました マージ操作のみの実行計画 要点で。
正しい解決策はありません
所属していません StackOverflow