一時テーブルに30000個のIDを挿入する必要があります##MyTempTable
列が1つしかない(ID int
)と私はそれが私がそれを最も速く行うことができる方法を知りたいです。
通常の挿入を30000回試しました
insert into ##MyTempTable (ID) ...
私が試してみました
insert into ##MyTempTable (ID) (
select 1002000 union all
select 1002001 union all
select 1002002 ...
これまでの最速の方法は次のとおりです。
insert into ##MyTempTable (ID)
values
(1002000),(1002001),(1002002),(1002003) ...
このタイプの挿入は最大1,000行しか受け入れないため、その挿入を30回繰り返しました。
あなたは私を助けることができますか?
1002000から始めて、1ずつ増加する30000個のID値を挿入しようとしているだけの場合、C#で次のようなものよりも高速なものをすべてリグできるとは思えません。
INSERT ##MyTable(ID)
SELECT 1001999 + n FROM
(
SELECT TOP (30000) n = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
ORDER BY s1.[object_id]
) AS x;
私の卑劣なWindows VM Macホストでは、これは1秒未満で発生します。
ループなしでセット/シーケンスを生成する他のアイデアについては(たとえば、数値テーブルの方が速い場合があります)、次のブログシリーズを参照してください。
http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1
http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-2
http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-
値が定義されていて、インクリメンタルシーケンスではない場合(たとえば、30,000の値を何らかの方法でDataTableに強制変換した場合)、テーブル値パラメーターの使用を検討できます。最初に、データベースにこのタイプを作成します(これは1回だけ行います)。
CREATE TYPE dbo.MyIDs AS TABLE(ID INT PRIMARY KEY);
これを受け入れるストアドプロシージャを作成します。
CREATE PROCEDURE dbo.TakeMyIDs
@m dbo.MyIDs READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT ##MyTable(ID) SELECT ID FROM @m;
END
GO
次に、C#からストアドプロシージャを呼び出し、DataTableをパラメーターとして渡します。
// assuming an active connection object, conn,
// and a populated DataTable called dtIDs:
SqlCommand cmd = new SqlCommand("dbo.TakeMyIDs", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvp1 = cmd.Parameters.AddWithValue("@m", dtIDs);
tvp1.SqlDbType = SqlDbType.Structured;
cmd.ExecuteNonQuery();
cmd.Dispose();