TVP が他のオプションよりも「著しく遅い」場合は、それらを正しく実装していない可能性があります。
<オール>IEnumerable
の使用 コレクションをDBに送信するためだけにメモリ内でコレクションを複製しないため、インターフェースはより高速で、メモリの使用量が少なくなります。これは次の場所に文書化されています:- 1,000 万件のレコードを最短時間で挿入するにはどうすればよいですか? (ここにも多くの追加情報とリンクがあります)
- ストアド プロシージャ T-SQL に辞書を渡す
- ストリーミング データアプリケーションから SQL Server 2008 へ (SQLServerCentral.com で、無料の登録が必要です)
AddWithValue
を使用しないでください ただし、これはおそらくパフォーマンスの問題ではありません。それでも、次のようにする必要があります:
SqlParameter tvp =com.Parameters.Add("data", SqlDbType.Structured);tvp.Value =MethodThatReturnsIEnumerable(MyCollection);
プレ>
- 単純な SELECT 以外に TVP を使用するクエリでは、ステートメント レベルの再コンパイルを使用します:
OPTION (RECOMPILE)
- ローカル一時テーブルを作成します (つまり、単一の
#
)、TVP の内容を一時テーブルにコピーします - クラスター化された主キーをユーザー定義のテーブル タイプに追加してみてください
- SQL Server 2014 以降を使用している場合は、インメモリ OLTP / メモリ最適化テーブルの利用を試すことができます。参照してください:メモリ最適化による一時テーブルとテーブル変数の高速化
表示される理由について:
insert into @data ( ... fields ... ) values ( ... values ... )-- 各行に対してinsert into @data ( ... fields ... ) values ( .. . 値 ... )
プレ>代わりに:
insert into @data ( ... fields ... ) values ( ... values ... ), ( ... values ... ),
プレ>それが実際に起こっていることである場合:
- 挿入がトランザクション内で行われている場合、実際のパフォーマンスの違いはありません
- 新しい値リストの構文 (例:
VALUES (row1), (row2), (row3)
) は 1000 行程度に制限されているため、その制限がない TVP では実行可能なオプションではありません。INSERT INTO @data (fields) SELECT tab.[col] FROM (VALUES (), (), .. .) タブ([列])コード> 、ここに文書化しました:テーブル値コンストラクターの最大行数 .代わりに...
- その理由として最も可能性が高いのは、個々の挿入を行うことで、アプリ コードから SQL Server に値をストリーミングできるためです。 <オール>
- 反復子を使用する (つまり、
IEnumerable
上記の #1 に記載)、アプリ コードはメソッドから返された各行を送信し、 VALUES (), (), ...
の構築INSERT INTO ... SELECT FROM (VALUES ...)
を実行している場合でも、リスト 全体を構築する必要があるアプローチ (1000 行に限定されない)値
何かを送信する前にリスト データを SQL Server に転送します。大量のデータがあると、非常に長い文字列を作成するのに時間がかかり、作成中に多くのメモリを消費します。
次の SQL Server カスタマー アドバイザリ チームのホワイト ペーパーも参照してください。 -with-tvp.aspx">TVP によるスループットの最大化