Fastest way to insert 1 million rows in SQL Server [duplicate] Fastest way to insert 1 million rows in SQL Server [duplicate] sql sql

Fastest way to insert 1 million rows in SQL Server [duplicate]

I think what you are looking for is Bulk Insert if you prefer using SQL.

Or there is also the ADO.NET for Batch Operations option, so you keep the logic in your C# application. This article is also very complete.


Yes I'm afraid bulk insert will only work with imported files (from within the database).

I have an experience in a Java project where we needed to insert millions of rows (data came from outside the application btw).

Database was Oracle, so of course we used the multi-line insert of Oracle. It turned out that the Java batch update was much faster than the multi-valued insert of Oracle (so called "bulk updates").

My suggestion is:

If the data you are going to manipulate is coming from outside your application (if it is not already in the database), I would say just go for the ADO.NET Batch Inserts. I think that its your case.

Note: Keep in mind that batch inserts usually operate with the same query. That is what makes them so fast.

Calling a prc in a loop incurs many round trips to SQL.

Not sure what batching approach you used but you should look into table value parameters: Docs are here. You'll want to still batch write.

You'll also want to consider memory on your server. Batching (say 10K at a time) might be a bit slower but might keep memory pressure lower on your server since you're buffering and processing a set at a time.

Table-valued parameters provide an easy way to marshal multiple rows of data from a client application to SQL Server without requiring multiple round trips or special server-side logic for processing the data. You can use table-valued parameters to encapsulate rows of data in a client application and send the data to the server in a single parameterized command. The incoming data rows are stored in a table variable that can then be operated on by using Transact-SQL.

Another option is bulk insert. TVPs benefit from re-use however so it depends on your usage pattern. The first link has a note about comparing:

Using table-valued parameters is comparable to other ways of using set-based variables; however, using table-valued parameters frequently can be faster for large data sets. Compared to bulk operations that have a greater startup cost than table-valued parameters, table-valued parameters perform well for inserting less than 1000 rows.

Table-valued parameters that are reused benefit from temporary table caching. This table caching enables better scalability than equivalent BULK INSERT operations.

Another comparison here: Performance of bcp/BULK INSERT vs. Table-Valued Parameters

Here is an example what I've used before with SqlBulkCopy. Grant it I was only dealing with around 10,000 records but it did it inserted them a few seconds after the query ran. My field names were the same so it was pretty easy. You might have to modify the DataTable field names. Hope this helps.

private void UpdateMemberRecords(Int32 memberId)    {    string sql = string.Format("select * from Member where mem_id > {0}", memberId);    try {        DataTable dt = new DataTable();        using (SqlDataAdapter da = new SqlDataAdapter(new SqlCommand(sql, _sourceDb))) {            da.Fill(dt);        }        Console.WriteLine("Member Count: {0}", dt.Rows.Count);        using (SqlBulkCopy sqlBulk = new SqlBulkCopy(ConfigurationManager.AppSettings("DestDb"), SqlBulkCopyOptions.KeepIdentity)) {            sqlBulk.BulkCopyTimeout = 600;            sqlBulk.DestinationTableName = "Member";            sqlBulk.WriteToServer(dt);        }    } catch (Exception ex) {        throw;    }}