我知道这些问题相当普遍,但我一整天都在搜索,但我找不到合适的方法。
这是我的代码,使用C#将大约100 000条虚拟记录插入MDB文件。
OleDbConnection con = new OleDbConnection();
string dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;";
string dbSource = "Data Source = D:/programming/sample.mdb";
con.ConnectionString = dbProvider + dbSource;
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandText = "INSERT INTO tblBooks (Title, Price, Tag, Author) VALUES (@title, @price, @tag, @author)";
cmd.Parameters.AddWithValue("@title", "Dummy Text 1");
cmd.Parameters.AddWithValue("@price", 10);
cmd.Parameters.AddWithValue("@tag", "Dummy Text 2");
cmd.Parameters.AddWithValue("@author", "Dummy Text 3");
con.Open();
for (int i = 0; i < 100000; i++)
{
cmd.ExecuteNonQuery();
}
con.Close();
此代码大约需要一分钟才能运行。这是正常的吗?更快地做到这一点的正确方法是什么?
答案 0 :(得分:5)
如果你碰巧已经有一个“数字表”(至少有100,000行),那么Remou的回答几乎肯定能让你的工作最快完成。我在VBA和查询中尝试了快速测试
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"
在不到2秒的时间内创建了100,000行。
但是,如果您还没有数字表,那么您需要先创建该表,因此如果这是一次性要求,那么您可能最好只是优化代码。
您的问题中发布的代码在我的计算机上花了45秒。两项显着缩短执行时间的增强功能是:
使用.Prepare()
:单独将经过的时间减少到16秒
使用OleDbTransaction
:在事务中包装插入(除了使用.Prepare()
之外)还会将已用时间缩短为10秒。
修改后的代码如下所示:
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));
答案 1 :(得分:3)
(奖金回答:)
如果有人想知道OleDbDataAdapter
是否可以更快插入行,似乎没有。以下代码确实创建了100,000条记录......
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);
...但运行时间比问题中的原始代码长约30%。
答案 2 :(得分:1)
您可以使用数字表添加多个相同的行,例如:
INSERT INTO aTable ( aText, aNumber )
SELECT @param1 , @param2
FROM Numbers
WHERE Numbers.Number<1000
Numbers表是:
Number
0
1
2
<...>