[英]MS Access Batch Update via ADO.Net and COM Interoperability
这是这个帖子的后续行动。 这都是.Net 2.0 ; 对我来说,至少。
从本质上讲,Marc(上面的OP)尝试了几种不同的方法来更新具有100,000条记录的MS Access表,并发现使用DAO连接比使用ADO.Net 快大约10-30倍 。 我走了几乎相同的路径(下面的例子)并得出了相同的结论。
我想我只是想了解为什么 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
委托直接到MS Access等价物,它决不会生成SQL,因此MS Access无法解析SQL。
另一方面,DataAdapter代码为每一行生成一个Update语句,该更新语句将传递给ODBC,然后ODBC将其传递给MSAccess驱动程序,该驱动程序要么
AddNew
和Update
命令 AddNew
和Update
命令。 无论哪种方式,你的时间都会产生SQL,然后有一些东西解释SQL,DAO方法绕过SQL生成/解释并直接进入金属。
解决此问题的一种方法是使用访问db创建在计算机上运行的自己的“数据库服务”。 这会整理您的选择和更新,并可以通过远程处理,WCF(http或其他)与客户端进行通信。 这是一项很多工作,并且会大大改变您的应用程序逻辑。
确定数据库驱动程序的正确名称(例如Jet或其他)是留给读者的练习
我知道这个问题已经过时了,但答案可能会帮助那些仍在努力解决这个问题的人。
还有另一种方法需要考虑。 由于源连接字符串和目标连接字符串都是已知的,源表可以链接到目标Access数据库,可能需要通过DAO或ADOX进行一些连接字符串解析(我知道,ADOX在这里是偏离主题的)。
通过在DAO或OleDb连接上向目标Access数据库发出这样的语句,可以相当快速地传输如此链接的表中的数据:
SELECT * INTO Table1 FROM _LINKED_Table1
一些缺点(请指出我错过的任何东西):
一些优点(请指出我错过的任何东西):
这种方法用于生产项目,至少对我来说是最快的。 :O)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.