0

私は次の声明を持っています:

UPDATE Table SET Column=Value WHERE TableID IN ({0})

非常に長くなる可能性がある TableID のカンマ区切りのリストがあります ({0} を置き換えるため)。これは SqlDataAdapter を使用するよりも高速であることがわかりましたが、コマンド テキストが長すぎると SqlCommand のパフォーマンスが低下する可能性があることにも気付きました。

何か案は?

これは、CLR トリガーの内部にあります。SqlCommand を実行するたびに、何らかのオーバーヘッドが発生します。私は、上記のコマンドが SqlDataAdapter.Update() よりも優れていると判断しました。なぜなら、Update() は、複数の SQL ステートメントを実行して個々のレコードを更新するからです。

...私は次のことをしました(トリガー時間が0.7秒から0.25秒になりました)

UPDATE T SET Column=Value FROM Table T INNER JOIN INSERTED AS I ON (I.TableID=T.TableID)
4

4 に答える 4

0

長いリストがある場合、実行プランはおそらくインデックスシークの代わりにインデックススキャンを使用しています。この場合、リストを複数のアイテムに制限することをお勧めしますが、リスト内のすべてのアイテムが収容されるまで、updateコマンドを繰り返し呼び出します。

于 2013-03-18T19:46:03.313 に答える
0

これがストアド プロシージャの場合は、テーブル値パラメーターを使用します。これがアドホック バッチである場合は、一時テーブルにデータを入力し、バッチでそれに結合することを検討してください。IN句は、インデックスの使用を非常に簡単に否定できる一連のORとして合理化されています。JOIN を使用すると、オプティマイザからより良い計画を取得できます。

DECLARE @Value VARCHAR(100) = 'Some value';
CREATE TABLE #Table (TableID INT PRIMARY KEY);
INSERT INTO #Table VALUES (1),(2),(3),(n)...;
MERGE INTO Schema.Table AS target
USING #Table AS source
ON target.TableID = source.TableID
WHEN MATCHED THEN UPDATE SET Column = Value;
于 2013-03-18T20:01:36.967 に答える
0

ID のリストをバッチに分割してください。コレクションにID番号のリストがあり、{0}文字列を作成していると思います。一度に 20 個または 100 個を更新することもできます。

トランザクションでラップし、Commit() を呼び出す前にすべての更新を実行します。

于 2013-03-18T19:46:49.467 に答える
0

ストアド プロシージャを使用できる場合は、MERGE代わりにステートメントを使用できます。

MERGE INTO Table AS target
USING @TableIDList AS source
ON target.TableID = source.ID
WHEN MATCHED THEN UPDATE SET Column = source.Value

where@TableIDListは、必要なs (場合によっては s) を持つテーブル値パラメーターとしてコードから送信されるテーブル型です。IDValue

于 2013-03-18T19:51:53.277 に答える