What is the fastest way to insert 100 000 records into an MDB file in C#

限于喜欢 提交于 2019-11-29 15:47:38

If you happen to already have a "numbers table" available (with at least 100,000 rows) then Remou's answer will almost certainly get the job done fastest. I tried a quick test in VBA and the query

Dim t0 As Single
t0 = Timer
CurrentDb.Execute _
        "INSERT INTO tblBooks (Title, Price, Tag, Author) " & _
        "SELECT 'Dummy Text 1', 10, 'Dummy Text 2', 'Dummy Text 3' FROM Numbers", _
        dbFailOnError
Debug.Print Format(Timer - t0, "0.0") & " seconds"

created the 100,000 rows in less than 2 seconds.

However, if you don't already have a numbers table then you would need to create that table first, so if this is a one-time requirement then you might be better off just optimizing your code.

The code as posted in your question took 45 seconds on my machine. Two enhancements that significantly reduced the execution time were:

  1. Use .Prepare(): that alone reduced the elapsed time to 16 seconds

  2. Use an OleDbTransaction: Wrapping the inserts in a transaction (in addition to using .Prepare()) further reduced the elapsed time to 10 seconds.

The modified code looks like this:

var sw = new System.Diagnostics.Stopwatch();
sw.Start();
OleDbConnection con = new OleDbConnection();
string dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;";
string dbSource = "Data Source = C:/Users/Gord/Desktop/speed.mdb";
con.ConnectionString = dbProvider + dbSource;
con.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandText = "INSERT INTO tblBooks (Title, Price, Tag, Author) VALUES (?,?,?,?)";
cmd.Parameters.Add("?", OleDbType.VarWChar, 255);
cmd.Parameters.Add("?", OleDbType.Currency);
cmd.Parameters.Add("?", OleDbType.VarWChar, 255);
cmd.Parameters.Add("?", OleDbType.VarWChar, 255);
cmd.Prepare();
cmd.Parameters[0].Value = "Dummy Text 1";
cmd.Parameters[1].Value = 10;
cmd.Parameters[2].Value = "Dummy Text 2";
cmd.Parameters[3].Value = "Dummy Text 3";
OleDbTransaction trn = con.BeginTransaction();
cmd.Transaction = trn;
for (int i = 0; i < 100000; i++)
{
    cmd.ExecuteNonQuery();
}
trn.Commit();
con.Close();
sw.Stop();
Console.WriteLine(String.Format("{0:0.0} seconds", sw.ElapsedMilliseconds / 1000.0));

(Bonus answer:)

In case anyone is wondering whether an OleDbDataAdapter can insert the rows faster, it seems not. The following code does create the 100,000 records...

var da = new OleDbDataAdapter("SELECT [ID], [Title], [Price], [Tag], [Author] FROM [tblBooks] WHERE False", con);
var cb = new OleDbCommandBuilder(da);
cb.QuotePrefix = "["; cb.QuoteSuffix = "]";
var dt = new System.Data.DataTable();
da.Fill(dt);
for (int i = 0; i < 100000; i++)
{
    System.Data.DataRow dr = dt.NewRow();
    dr["Title"] = "Dummy Text 1";
    dr["Price"] = 10;
    dr["Tag"] = "Dummy Text 2";
    dr["Author"] = "Dummy Text 3";
    dt.Rows.Add(dr);
}
da.Update(dt);

...but it takes about 30% longer to run than the original code in the question.

You can use a numbers table to add multiple identical rows, for example:

INSERT INTO aTable ( aText, aNumber )
SELECT @param1 , @param2 
FROM Numbers
WHERE Numbers.Number<1000

The Numbers table is:

Number
0
1
2
<...>
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!