这是对 this thread 的跟进。 .这就是 .Net 2.0 ;至少对我来说。
本质上,Marc(上面的 OP)尝试了几种不同的方法来更新具有 100,000 条记录的 MS Access 表,并发现使用 DAO 连接大致为 。快 10 - 30 倍 比使用 ADO.Net。我走了几乎相同的路径(下面的示例)并得出了相同的结论。
我想我只是想了解为什么 OleDB 和 ODBC 的速度要慢得多,我很想知道自 2011 年那篇文章以来是否有人找到比 DAO 更好的答案。我真的更愿意避免 DAO 和/或自动化,因为它们需要客户端机器具有 Access 或可再分发的数据库引擎(或者我坚持使用不支持 .ACCDB 的 DAO 3.6)。
最初的尝试; 100,000 条记录/10 列约 100 秒:
Dim accessDB As New OleDb.OleDbConnection( _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
accessPath & ";Persist Security Info=True;")
accessDB.Open()
Dim accessCommand As OleDb.OleDbCommand = accessDB.CreateCommand
Dim accessDataAdapter As New OleDb.OleDbDataAdapter( _
"SELECT * FROM " & tableName, accessDB)
Dim accessCommandBuilder As New OleDb.OleDbCommandBuilder(accessDataAdapter)
Dim accessDataTable As New DataTable
accessDataTable.Load(_Reader, System.Data.LoadOption.Upsert)
//This command is what takes 99% of the runtime; loops through each row and runs
//the update command that is built by the command builder. The problem seems to
//be that you can't change the UpdateBatchSize property with MS Access
accessDataAdapter.Update(accessDataTable)
无论如何,我觉得这真的很奇怪,所以我尝试了几种相同的口味:
最后,我尝试使用 DAO。代码基本上应该做同样的事情;但显然不是,因为它在大约 10 秒内运行。
Dim dbEngine As New DAO.DBEngine
Dim accessDB As DAO.Database = dbEngine.OpenDatabase(accessPath)
Dim accessTable As DAO.Recordset = accessDB.OpenRecordset(tableName)
While _Reader.Read
accessTable.AddNew()
For i = 0 To _Reader.FieldCount - 1
accessTable.Fields(i).Value = _Reader.Item(i).ToString
Next
accessTable.Update()
End While
其他一些注意事项:
希望有人能够对此有所了解……这很奇怪。
提前致谢!
最佳答案
这里的原因是 DAO 驱动程序比 ODBC 驱动程序更接近 MS Access 数据库引擎。
DAO 方法 AddNew
和 Update
直接委托(delegate)给 MS Access 等效项,它在任何时候都不会生成 SQL,因此 MS Access 没有要解析的 SQL。
另一方面,DataAdapter 代码为每一行生成一个更新语句,该更新语句被传递给 ODBC,然后由它传递给 MSAccess 驱动程序,该驱动程序要么
AddNew
和 Update
Access 数据库或 并且一旦解析,最终将 SQL 转换为
AddNew
和Update
命令。 无论哪种方式,您都需要花费时间生成 SQL,然后让一些东西解释该 SQL,其中 DAO 方法绕过 SQL 生成/解释并直接进入金属。
解决此问题的一种方法是创建您自己的“数据库服务”,该服务在具有 Access 数据库的机器上运行。这会编码您的选择和更新,并可以通过远程处理、WCF(http 或其他)与客户端进行通信。这是很多工作,并且会极大地改变您的应用程序逻辑。
找出数据库驱动程序的正确名称(例如 Jet 或其他)是留给读者的练习
关于.net - 通过 ADO.Net 和 COM 互操作性进行 MS Access 批量更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15788441/