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

Posted

技术标签:

【中文标题】在 C# 中将 100 000 条记录插入 MDB 文件的最快方法是啥【英文标题】:What is the fastest way to insert 100 000 records into an MDB file in C#在 C# 中将 100 000 条记录插入 MDB 文件的最快方法是什么 【发布时间】:2014-03-17 23:48:27 【问题描述】:

我知道这个问题相当笼统,但我已经搜索了一整天,但找不到正确的方法。

这是我使用 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 到您需要的最大数字的整数,然后您可以不使用逐行插入。 我认为如果 COM 和/或 activeX 在 C# 中可用,最好使用 DAO 或 ADO 对象 @Remou 您能否针对这种情况进一​​步解释一下? ***.com/questions/7070011/… @user3393415 非常感谢您的链接,欢迎来到 SO :) 【参考方案1】:

如果您碰巧已经有一个可用的“数字表”(至少有 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));

【讨论】:

非常感谢,这对我帮助很大。我设法将时间减少到 10.1 秒,接下来我将查看数字表。【参考方案2】:

(奖励答案:)

如果有人想知道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%。

【讨论】:

感谢 Gord 您与我们分享的所有知识。更新呢?我对此提出了另一个问题。 ***.com/questions/21859395/…【参考方案3】:

您可以使用数字表添加多个相同的行,例如:

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

数字表是:

Number
0
1
2
<...>

【讨论】:

你的意思是,首先我需要创建空白记录并用整数填充它们,然后我可以用正确的值更新其他字段? 我的意思是你需要一个数字表 (***.com/questions/1393951/…)。这是非常有用的。在上面的示例中,numbers 表仅用于获取所需的行数。数字表中的数据仅用作计数。您可以看到选择数据包含两个参数,但不是数字表中保存的单个字段。 抱歉,我无法理解这一点 :( 我需要创建一个包含 100 000 行和多个字段的 MDB 文件,并且我需要用数据填充它们,我该如何实现你的方法在我的代码中。抱歉,如果我遗漏了明显的内容。 首先,创建或导入一个数字表,在您的查询中使用数字表。每个数据库应该有的两个表是一个数字表和一个日期表。示例中的所有 numbers 表都消除了对 for (int i = 0; i &lt; 100000; i++) 的需要。您可以在插入表中拥有任意数量的字段,但所有字段在行与行之间都是相同的。数字表是可重复使用的。

以上是关于在 C# 中将 100 000 条记录插入 MDB 文件的最快方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

在 Redshift 中获取超过 100,000 条记录 [关闭]

在 NodeJS 中将 200'000 行以上的大型 csv 文件插入 MongoDB

在 NodeJS 中将 200'000 行以上的大型 csv 文件插入 MongoDB

Postgresql 内存表空间中的插入速度慢

Java更新100条记录在一定时间后需要很长时间

我们如何在 C# 中将访问数据库(.mdb)导入 sql server 2008