MS Access: Perché è così ADODB.Recordset.BatchUpdate molto più lento di Application.ImportXML?

StackOverflow https://stackoverflow.com/questions/2986831

Domanda

Sto cercando di eseguire il codice qui sotto per inserire un sacco di dischi (da un file con un formato di file strano) nel mio database Access 2003 da VBA. Dopo molti, molti esperimenti, questo codice è il più veloce che ho potuto venire con: lo fa 10000 record in circa 15 secondi sulla mia macchina. Almeno 14,5 di quei secondi (es. Quasi tutto il tempo) è in singola chiamata a UpdateBatch.

Ho letto altrove che il motore Jet non supporta UpdateBatch. Così forse c'è un modo migliore per farlo.

Ora, vorrei solo pensare il motore JET è semplice lento, ma che non può essere così. Dopo aver generato la tabella 'irascibile' con il codice qui sotto, ho ragione cliccato su, preso Export, e salvato in formato XML. Poi ho cliccato destra, raccolte di importazione, e ricaricato l'XML. Tempo totale di importare il file XML? Meno di un secondo, cioè. almeno 15x più veloce.

Sicuramente c'è un modo efficace per inserire i dati in Access che non richiede la scrittura di un file temporaneo?

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

I sarebbe disposto a ricorrere a C / C ++, se c'è qualche API che mi permetta di fare inserti veloci in quel modo. Ma io non riesco a trovarlo. Non può essere che Application.ImportXML sta usando le API non documentate, può?

È stato utile?

Soluzione

A meno che non si deve fare questo con ADO, tenta invece DAO. Qui ci sono i tempi sul mio portatile con la vostra procedura e una versione di 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

Questa è la versione DAO che ho usato.

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top