MS Access Batch Update über ADO.Net und COM Interoperabilität

Dies ist eine Art Follow-up zudieser Thread. Das ist alles mit.Net 2.0; für mich zumindest.

Im Wesentlichen hat Marc (OP von oben) verschiedene Ansätze zum Aktualisieren einer MS Access-Tabelle mit 100.000 Datensätzen ausprobiert und festgestellt, dass die Verwendung einer DAO-Verbindung ungefähr war10 - 30x schneller als mit ADO.Net. Ich bin praktisch den gleichen Weg gegangen (Beispiele unten) und bin zu dem gleichen Schluss gekommen.

Ich versuche nur zu verstehenWarum OleDB und ODBC sind so viel langsamer und ich würde gerne hören, ob jemand seit diesem Beitrag im Jahr 2011 eine bessere Antwort als DAO gefunden hat. Ich würde es wirklich vorziehen, DAO und / oder Automatisierung zu vermeiden, da sie den Client benötigen werden Maschine entweder Zugriff oder die Datenbank-Engine weitervertreibbar haben (oder ich bin mit DAO 3.6, die nicht unterstützt .ACCDB stecken).

Ursprünglicher Versuch; ~ 100 Sekunden für 100.000 Datensätze / 10 Spalten:

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)

Wie auch immer, ich fand das wirklich seltsam, also habe ich verschiedene Varianten der gleichen Sache ausprobiert:

OleDB für ODBC ausschaltenDurchlaufen Sie die Datentabelle und führen Sie für jede Zeile eine INSERT-Anweisung ausDas macht .Update sowiesoVerwenden des ACE-Providers anstelle von Jet (ODBC und OleDB)Ausführen des Datenadapter-Updates in der DataReader.Read-SchleifeAus Frustration; es war lustig.

Schließlich habe ich versucht, DAO zu verwenden. Der Code sollte im Grunde das Gleiche tun. außer es ist eindeutig nicht, weil es in ~ 10 Sekunden läuft.

 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

Ein paar andere Anmerkungen:

In allen Beispielen wird alles in Strings konvertiert, um die Dinge so einfach und konsistent wie möglich zu haltenAusnahme: In meinem ersten Beispiel mit der Table.Load - Funktion tue ich das nicht, weil ... nun, ich kann es wirklich nicht, aber ich habe im Grunde dasselbe getan, als ich den Reader durchlaufen und Einfügebefehle erstellt habe (das ist was es sowieso tut). Es hat nicht geholfen.Für jedes Feld ... Weiter gegen Feld (i) gegen Feld (Name) machte für mich keinen UnterschiedJeder von mir durchgeführte Test begann mit einer leeren, vorgefertigten Datentabelle in einer frisch komprimierten Access-DatenbankDas Laden des Datenlesegeräts in eine Datentabelle im Speicher dauert ca. 3 SekundenIch denke nicht, dass es ein Problem beim Marshallen der Daten ist, da Marc's Post angab, dass das Laden einer Textdatei über Automation so schnell ist wie DAO - wenn überhaupt, sollte es die Daten nicht marshallen, wenn ODBC / OleDB verwendet wird, aber essollte bei der Verwendung von AutomationAll dies stört mich viel mehr als es sollte, weil es keinen Sinn ergibt

Hoffentlich kann jemand etwas Licht ins Dunkel bringen ... es ist nur seltsam. Danke im Voraus!

Antworten auf die Frage(2)

Ihre Antwort auf die Frage