在C#中将100 000条记录插入MDB文件的最快方法是什么?

时间:2014-02-18 10:00:17

标签: c# ms-access oledb

我知道这些问题相当普遍,但我一整天都在搜索,但我找不到合适的方法。

这是我的代码,使用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();

此代码大约需要一分钟才能运行。这是正常的吗?更快地做到这一点的正确方法是什么?

3 个答案:

答案 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秒。两项显着缩短执行时间的增强功能是:

  1. 使用.Prepare():单独将经过的时间减少到16秒

  2. 使用OleDbTransaction:在事务中包装插入(除了使用.Prepare()之外)还会将已用时间缩短为10秒。

  3. 修改后的代码如下所示:

    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
<...>