MERGE
アプリケーションから入力したデータを使用して、データベースにアップサート操作を作成するクエリがあります。大規模なトランザクション(> 5000)でデータを保存するために呼び出すと、非常に長い時間(〜20〜40秒)かかります。
これが私のMERGE
声明です
MERGE TestTable AS target USING (SELECT @Guid) AS source (target.Guid = source.Guid)
WHEN MATCHED THEN
UPDATE TestTable SET Column1 = @Column1, Column2 = @Column2 WHERE Guid = @Guid
WHEN NOT MATCHED THEN
INSERT INTO TestTable (Column1, Column2) VALUES (@Column1, @Column2)
OUTPUT $action
.NETコードで一度に1つのオブジェクトでこれを呼び出しています。
SQL Express 2008 Activity MonitorのActivityMonitorで、クエリが呼び出されているさまざまなパラメーターの順列が原因で、プラン数が最大で約900になることに気付きました。また、わずかに異なるパラメーターを使用してすぐに同じ保存を繰り返すと、はるかに速く(〜2秒)保存されることに気付きました。
これは潜在的なパフォーマンスの問題であり、保存時間が長くなる原因ですか?
SQL Express2008R2を使用しています。
編集:これが計画です:
|--Compute Scalar(DEFINE:([Expr1044]=CASE WHEN [Action1004]=(1) THEN N'UPDATE' ELSE CASE WHEN [Action1004]=(4) THEN N'INSERT' ELSE N'DELETE' END END))
|--Assert(WHERE:(CASE WHEN NOT [Pass1238] AND [Expr1237] IS NULL THEN (0) ELSE NULL END))
|--Nested Loops(Left Semi Join, PASSTHRU:([Action1004]=(3) OR [C:\DATABASE.MDF].[dbo].[DoorTable].[CarTable_Guid] as [target].[CarTable_Guid] IS NULL), OUTER REFERENCES:([C:\DATABASE.MDF].[dbo].[DoorTable].[CarTable_Guid]), DEFINE:([Expr1237] = [PROBE VALUE]))
|--Clustered Index Merge(OBJECT:([C:\DATABASE.MDF].[dbo].[DoorTable].[DoorTable_PK] AS [target]), OBJECT:([C:\DATABASE.MDF].[dbo].[DoorTable].[DoorTable_FI01] AS [target]), SET:(Insert, [C:\DATABASE.MDF].[dbo].[DoorTable].[Column1] as [target].[Column1] = [Expr1005],[C:\DATABASE.MDF].[dbo].[DoorTable].[Column2] as [target].[Column2] = [Expr1006],[C:\DATABASE.MDF].[dbo].[DoorTable].[Column3] as [target].[Column3] = [Expr1007],[C:\DATABASE.MDF].[dbo].[DoorTable].[Column4] as [target].[Column4] = [Expr1008],[C:\DATABASE.MDF].[dbo].[DoorTable].[Column5] as [target].[Column5] = [Expr1009],[C:\DATABASE.MDF].[dbo].[DoorTable].[Column6] as [target].[Column6] = [Expr1010],[C:\DATABASE.MDF].[dbo].[DoorTable].[Column7] as [target].[Column7] = [Expr1011],[C:\DATABASE.MDF].[dbo].[DoorTable].[Column8] as [target].[Column8] = [Expr1012],...
| |--Compute Scalar(DEFINE:([Action1004]=[Action1004], [Expr1198]=[Expr1198]))
| |--Top(TOP EXPRESSION:((1)))
| |--Compute Scalar(DEFINE:([Expr1198]=CASE WHEN [Action1004] = (1) THEN CASE WHEN [Expr1099] THEN (0) ELSE (1) END ELSE [Action1004] END))
| |--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(nvarchar(64),[@Column1],0), [Expr1006]=CONVERT_IMPLICIT(nvarchar(64),[@Column2],0), [Expr1007]=CONVERT_IMPLICIT(nvarchar(64),[@Column3],0), [Expr1008]=[@Column4], [Expr1009]=CONVERT_IMPLICIT(nvarchar(64),[@Column5],0), [Expr1010]=[@Column6], [Expr1011]=[@Column7], [Expr1012]=CONVERT_IMPLICIT(float(53),[@Column8],0),[Expr1099]=[Action1004]=(1) AND CASE WHEN [C:\DATABASE.MDF].[dbo].[DoorTable].[CarTable_Guid] as [target].[CarTable_Guid] = CONVERT_IMPLICIT(nvarchar(32),[@CarTable_Guid],0) THEN (1) ELSE (0) END))
| |--Compute Scalar(DEFINE:([Action1004]=ForceOrder(CASE WHEN [TrgPrb1002] IS NOT NULL THEN (1) ELSE (4) END)))
| |--Nested Loops(Left Outer Join)
| |--Constant Scan
| |--Compute Scalar(DEFINE:([TrgPrb1002]=(1)))
| |--Clustered Index Seek(OBJECT:([C:\DATABASE.MDF].[dbo].[DoorTable].[DoorTable_PK] AS [target]), SEEK:([target].[Guid]=CONVERT_IMPLICIT(nvarchar(1),[@Guid],0)) ORDERED FORWARD)
|--Clustered Index Seek(OBJECT:([C:\DATABASE.MDF].[dbo].[CarTable].[CarTable_PK]), SEEK:([C:\DATABASE.MDF].[dbo].[CarTable].[Guid]=[C:\DATABASE.MDF].[dbo].[DoorTable].[CarTable_Guid] as [target].[CarTable_Guid]) ORDERED FORWARD)