実行に7,387ミリ秒かかる内部結合を持つSQL Server 2012ストアドプロシージャがあります(アクティビティモニターで確認しました)。
[...]
declare @childrenIds as dbo.CodeIdList;
[...]
Update
dbo.Code
set
dbo.Code.CommissioningFlag = 21
From
dbo.Code
INNER JOIN
@childrenIds c
ON
dbo.Code.CodeId = c.CodeId
CodeIdList
は:
CREATE TYPE [dbo].[CodeIdList] AS TABLE (
[CodeId] INT NULL
);
INNER JOIN
を使用するよりも速くコードテーブルを更新する方法はありますか?
私はdbaではないので、私の質問の詳細が必要かどうかはわかりません。必要な方はお問い合わせください。
コードテーブルでsp_helpindex
を実行して、次の結果を得ました。
index_name | index_description PK_CODE |クラスタ化された一意の主キーがPRIMARYにあります。 CodeId UC_CODE_SERIAL |非クラスター化された一意の一意のキーがPRIMARYにあります。シリアル
Code
テーブル作成スクリプト:
CREATE TABLE [dbo].[Code] (
[CodeId] INT IDENTITY (1, 1) NOT NULL,
[Serial] NVARCHAR (20) NOT NULL,
[ ...]
CONSTRAINT [PK_CODE] PRIMARY KEY CLUSTERED ([CodeId] ASC),
CONSTRAINT [UC_CODE_SERIAL] UNIQUE NONCLUSTERED ([Serial] ASC)
)
現時点では、コードテーブルに1.006.896行あります。
実行計画:
http://Pastebin.com/9yXsRfva のXMLバージョン
SQL Serverのバージョン情報:
Microsoft SQL Server Management Studio 11.0.6020.0 Herramientas cliente de Microsoft Analysis Services 11.0.6020.0 Microsoft Data Access Components(MDAC)6.1.7601.17514 Microsoft MSXML 3.0 4.0 6.0 Microsoft Internet Explorer 9.11.9600.18314 Microsoft .NET Framework 4.0.30319.42000 Sistema operativo 6.1.7601
Select @@VERSION
:
Microsoft SQL Server 2012(SP3)(KB3072779)-11.0.6020.0(X64) Oct 20 2015 15:36:27 著作権(c)Microsoft Corporation Enterprise Edition(64 -bit)on Windows NT 6.1(Build 7601:Service Pack 1)
私はこのインデックスを追加しました、そしてそれは結合を0ms平均持続時間にスピードアップしました:
CREATE INDEX [IDX_FLAG_LEVEL_CODE]
ON Code (CommissioningFlag, AggregationLevelId)
INCLUDE (Serial, CodeId);
前の質問 を解決しているときに、偶然に解決策を見つけました。
サービスパックレベルを指定しませんでしたが、チェックアウトすることをお勧めします this post Aaron Bertrandから、2012 Service Pack 2のトレースフラグについて ' might 'テーブル変数に対して結合するときのパフォーマンスを改善します。投稿によると:
「テーブル変数がSQL Serverの他のテーブルと結合されている場合、SQL Serverは統計をサポートしていないか、クエリプランのコンパイル中にテーブル変数内の行数を追跡しないため、非効率的なクエリプランの選択によりパフォーマンスが低下する可能性があります。」
さらに、テーブル変数の代わりに一時テーブルを使用すると違いが生じるかどうかを確認することは興味深いでしょう。
「実際の」実行プランのXMLを投稿すると、結合がどのように実行されているかについてより多くの情報が得られる場合があります。
<> 21を追加して、すでに設定されているものをスキップできるようにします
Update dbo.Code
set dbo.Code.CommissioningFlag = 21
From dbo.Code
JOIN @childrenIds c
ON dbo.Code.CodeId = c.CodeId
where dbo.Code.CommissioningFlag <> 21 or dbo.Code.CommissioningFlag is null
CodeIDがCodeIdListで一意である場合、それをPKとして宣言するとおそらく役立つ
UPDATE
ステートメント
UPDATE dbo.Code
SET dbo.Code.CommissioningFlag = 21
FROM dbo.Code
INNER JOIN @childrenIds c
ON dbo.Code.CodeId = c.CodeId;
@childrenIds
は一意であり、nullであってはならないことを示唆しています。
してみてください
DECLARE @childrenIds AS table ([CodeId] int PRIMARY KEY);
また、@childrenIds
にデータを入力するときは、この制約に注意してください(どの時点でも@childrenIds
に重複またはNULL CodeId
を挿入しないように注意してください)。