MS Access: Warum ist adodb.recordset.batchupdate so viel langsamer als application.importxml?
-
24-10-2019 - |
Frage
Ich versuche, den folgenden Code auszuführen, um viele Datensätze (aus einer Datei mit einem seltsamen Dateiformat) in meine Access 2003 -Datenbank von VBA einzugeben. Nach vielen, vielen Experimenten ist dieser Code der schnellste, was ich mir vorstellen konnte: Er macht 10000 Datensätze in ungefähr 15 Sekunden auf meiner Maschine. Mindestens 14,5 dieser Sekunden (dh fast die ganze Zeit) befinden sich im Einzelaufruf zum UpdateBatch.
Ich habe an anderer Stelle gelesen, dass der Jet -Engine UpdateBatch nicht unterstützt. Vielleicht gibt es also einen besseren Weg, es zu tun.
Jetzt würde ich nur denken, dass der Strahlmotor langsam langsam ist, aber das kann es nicht sein. Nachdem ich die Tabelle "Testy" mit dem folgenden Code generiert hatte, habe ich mit der rechten Maustaste geklickt, den Export ausgewählt und als XML gespeichert. Dann habe ich mit der rechten Maustaste geklickt, importierte und die XML neu geladen. Gesamtzeit zum Importieren der XML -Datei? Weniger als eine Sekunde, dh. mindestens 15x schneller.
Sicherlich gibt es eine effiziente Möglichkeit, Daten in Zugriff einzufügen, bei denen kein Temp -Datei geschrieben werden muss?
Sub TestBatchUpdate()
CurrentDb.Execute "create table testy (x int, y int)"
Dim rs As New ADODB.Recordset
rs.CursorLocation = adUseServer
rs.Open "testy", CurrentProject.AccessConnection, _
adOpenStatic, adLockBatchOptimistic, adCmdTableDirect
Dim n, v
n = Array(0, 1)
v = Array(50, 55)
Debug.Print "starting loop", Time
For i = 1 To 10000
rs.AddNew n, v
Next i
Debug.Print "done loop", Time
rs.UpdateBatch
Debug.Print "done update", Time
CurrentDb.Execute "drop table testy"
End Sub
Ich wäre bereit, auf C/C ++ zurückzugreifen, wenn es eine API gibt, mit der ich schnell einfügen würde. Aber ich kann es nicht finden. Es kann nicht sein, dass application.importxml undokumentierte APIs verwendet, oder?
Lösung
Wenn Sie dies nicht mit ADO tun müssen, versuchen Sie es stattdessen dao. Hier sind die Zeiten auf meinem Laptop mit Ihrer Prozedur und einer Dao -Version:
ADO:
starting loop 9:51:59 PM
done loop 9:52:00 PM
done update 9:52:54 PM
DAO:
starting loop 9:58:29 PM
done loop 9:58:31 PM
done update 9:58:31 PM
Dies ist die DAO -Version, die ich verwendet habe.
Sub TestBatchUpdateDAO()
CurrentDb.Execute "create table testy (x int, y int)"
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("testy", dbOpenTable, dbAppendOnly)
Dim i As Long
Debug.Print "starting loop", Time
For i = 1 To 10000
rs.AddNew
rs!x = 50
rs!y = 55
rs.Update
Next i
Debug.Print "done loop", Time
'rs.UpdateBatch '
Debug.Print "done update", Time
rs.Close
Set rs = Nothing
CurrentDb.Execute "drop table testy"
End Sub