web-dev-qa-db-ja.com

SQL Serverに3万行を挿入する最速の方法

一時テーブルに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回繰り返しました。

あなたは私を助けることができますか?

4
Jenninha

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();
4
Aaron Bertrand