MS Access: Pourquoi est-ADODB.Recordset.BatchUpdate tellement plus lent que Application.ImportXML?
-
24-10-2019 - |
Question
Je suis en train d'exécuter le code ci-dessous pour insérer beaucoup d'enregistrements (à partir d'un fichier avec un format de fichier bizarre) dans ma base de données Access 2003 à partir de VBA. Après de nombreuses, de nombreuses expériences, ce code est le plus rapide que je suis en mesure de venir avec: il fait 10000 enregistrements en 15 secondes environ sur ma machine. Au moins 14,5 de ces secondes (ie. Presque tout le temps) est dans l'appel unique UpdateBatch.
J'ai lu ailleurs que le moteur JET ne supporte pas UpdateBatch. Alors peut-être qu'il ya une meilleure façon de le faire.
Maintenant, je pense que le moteur JET est clair lent, mais qui ne peut l'être. Après avoir généré la table « grincheux » avec le code ci-dessous, je faites un clic droit il, pris Export, et enregistré au format XML. Puis je faites un clic droit, choisi Importation et rechargées XML. Le temps total pour importer le fichier XML? Moins d'une seconde, à savoir. au moins 15x plus rapide.
Certes, il est un moyen efficace d'insérer des données dans Access qui ne nécessite pas l'écriture d'un fichier temporaire?
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
je serais disposé à recourir à C / C ++, s'il y a une API qui me permettrait de faire des inserts rapides de cette façon. Mais je ne peux pas sembler trouver. Il ne peut être que Application.ImportXML utilise des API non documentées, peut-il?
La solution
Sauf si vous devez le faire avec ADO, essayez DAO à la place. Voici les temps sur mon ordinateur portable avec votre procédure et une version DAO:
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
Ceci est la version DAO je.
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