0

でテーブル値パラメータのデータをフィルタリングします。私は、このストアドプロシージャ(現在MERGEおよびINSERT)上のいくつかの操作を実行しますが、それらの前に、私は述語にパラメータの内容をフィルタリングする:は、効率的に、私はそれで数千行まで何もして、ストアドプロシージャのパラメータとしてテーブル値タイプを持っているストアドプロシージャ

@data TableValuedType READONLY 

MERGE INTO Table2 
USING (
    SELECT ... FROM @data 
    UNION 
    SELECT ... FROM @data 
    UNION 
    ...) 
ON ... 
WHEN NOT MATCHED THEN .... 

INSERT INTO Table3 
    SELECT ... FROM @data 

を宣言するために、これを行うための最も効率的な方法ですテーブルタイプの別の変数、それに挿入、その後、合併から挿入するために、その変数を使用します。

DECLARE @sanitisedData TableValuedType 
INSERT INTO @sanitisedData 
    SELECT ... FROM @data 
    WHERE <predicate> 

または私は@dataから何かを選択するたびに述語を使用する:

MERGE INTO Table2 
USING (
    SELECT ... FROM @data WHERE <predicate> 
    UNION 
    SELECT ... FROM @data WHERE <predicate> 
    UNION 
    ...) 
ON ... 
WHEN NOT MATCHED THEN .... 

INSERT INTO Table3 
    SELECT ... FROM @data WHERE <predicate> 

など

+0

最初にフィルタリングされたデータセットを渡すことはできませんか? – Oded

+0

いいえ、フィルタリングを行う条件はサーバー上にのみ存在します – thecoop

+0

渡されたTVPを使用して結合を行っていますか? – Oded

答えて

0

は、可能な限り@Table変数の使用を避けるようにしてください。ほとんどの場合、パフォーマンスが低下します。代わりに一時テーブルを選択してください。

テーブル変数と一時テーブルの両方が、とにかくディスクに書き込まれ、それがクエリオプティマイザが使用できる統計情報が含まれているため、一時テーブルは、テーブル変数の上にさらなる利点を有します。また、一時表に索引(クラスタ化索引と非クラスタ化索引の両方)を作成できますが、表変数は作成できません。

だから私はあなたが一時テーブルを使用すると、あなたがすることによってフィルタリングされた列に索引を作成示唆しています。

これが役に立ちます。

+0

OPには「No、フィルタリングを行う条件はサーバー上にのみ存在します」というコメントがあります。これは、procが別のSPではなくクライアントによって呼び出されていることを示します。だから、このユースケースでは、おそらくテンポラリテーブルは現実的ではありません。しかし、BCPによって占有されるステージングテーブルは現実的な代替手段です –

+0

私は彼にSPの修正機能があると仮定していましたが、これが間違っていれば謝罪します。マージ/挿入の前にSP内で一時テーブルを作成することはできませんか? 私もステージングテーブルのオプションを提案するつもりでしたが、うれしく思いました。ありがとう。 – elvis

+0

実際に私はあなたの答えを誤解しているかもしれません。 '@Data'や' @ sanitisedData'を一時テーブルに置き換えることをお勧めしますか? –

関連する問題