This is kind of a follow-up to this thread. This is all with .Net 2.0; for me, at least.
Essentially, Marc (OP from above) tried several different approaches to update an MS Access table with 100,000 records and found that using a DAO connection was roughly 10 - 30x faster than using ADO.Net. I went down virtually the same path (examples below) and came to the same conclusion.
I guess I'm just trying to understand why OleDB and ODBC are so much slower and I'd love to hear if anyone has found a better answer than DAO since that post in 2011. I would really prefer to avoid DAO and/or Automation, since they're going to require the client machine to either have Access or the database engine redistributable (or I'm stuck with DAO 3.6 which doesn't support .ACCDB).
Original attempt; ~100 seconds for 100,000 records/10 columns:
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)
Anyway, I thought this was really odd so I tried several flavors of the same thing:
Finally, I tried using DAO. The code should basically be doing the same thing; except it clearly isn't, because it this runs in ~10 seconds.
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
A few other notes:
Hopefully someone will be able to shed some light on this... it's just strange. Thanks in advance!
The reason here is that the DAO driver sits much closer to the MS Access Database engine than the ODBC driver.
The DAO methods AddNew
and Update
delegate directly to MS Access equivalents, at no point does it generate SQL, so there's no SQL to be parsed by the MS Access.
On the other hand, the DataAdapter code generates an Update statement for each row, that update statement gets passed to ODBC, which then passes this to a MSAccess driver, which either
AddNew
and Update
commands to the Access database orAddNew
and
Update
commands.either way, your time is taken generating SQL and then having something interpret that SQL, where the DAO approach bypasses SQL generation / interpretation and goes straight to the metal.
One way around this is to create your own "database service" running on the machine with the access db. This marshals your selects & updates and could communicate with the client over remoting, WCF (http, or whatever). This is a lot of work and changes your application logic considerably.
Figuring out the correct name for the database driver (e.g. Jet or whatever) is an exercise left to the reader
I know this question is old but the answer may help someone still struggling with this.
There is another method to consider. As both source and target connection strings are known, source tables can be linked to the target Access database, possibly with some connection string parsing needed, via DAO or ADOX (I know, ADOX is off-topic here).
The data in tables so linked can then be transferred fairly quickly by issuing statements like this on a DAO or OleDb connection to the target Access database:
SELECT * INTO Table1 FROM _LINKED_Table1
Some drawbacks (please point out anything I missed):
Some advantages (please point out anything I missed):
This method was employed in a production project and turned out to be the quickest, for me at least. :o)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With