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:
Use .Prepare()
: that alone reduced the elapsed time to 16 seconds
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));
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…