MS Access: почему ADODB.Recordset.BatchUpdate намного медленнее, чем Application.ImportXML? - PullRequest
4 голосов
/ 07 июня 2010

Я пытаюсь запустить приведенный ниже код для вставки большого количества записей (из файла со странным форматом файла) в мою базу данных Access 2003 из VBA. После многих, многих экспериментов этот код является самым быстрым, который я смог придумать: он делает 10000 записей за 15 секунд на моей машине. По крайней мере 14,5 из этих секунд (то есть почти все время) находятся в одном вызове UpdateBatch.

В другом месте я читал, что движок JET не поддерживает UpdateBatch. Так что, возможно, есть лучший способ сделать это.

Теперь, я бы просто подумал, что движок JET довольно медленный, но этого не может быть. После создания таблицы 'testy' с приведенным ниже кодом, я щелкнул правой кнопкой мыши по ней, выбрал Экспорт и сохранил его в формате XML. Затем я щелкнул правой кнопкой мыши, выбрал Импорт и перезагрузил XML. Общее время для импорта файла XML? Менее одной секунды, т.е. по крайней мере, в 15 раз быстрее.

Конечно, есть эффективный способ вставить данные в Access, который не требует записи временного файла?

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

Я бы хотел прибегнуть к C / C ++, если бы был какой-то API, который позволял бы мне делать быстрые вставки таким образом. Но я не могу найти это. Не может быть, что Application.ImportXML использует недокументированные API, не так ли?

1 Ответ

3 голосов
/ 07 июня 2010

Если вам не нужно делать это с ADO, попробуйте вместо этого DAO. Вот время на моем ноутбуке с вашей процедурой и версией 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

Это версия DAO, которую я использовал.

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
...