MS Access:为什么 ADODB.Recordset.BatchUpdate 比 Application.ImportXML 慢这么多?

ape*_*arr 5 ms-access vba ado ms-jet-ace

我正在尝试运行下面的代码,将大量记录(来自具有奇怪文件格式的文件)从 VBA 插入到我的 Access 2003 数据库中。经过无数次的实验,这段代码是我能想到的最快的代码:它在我的机器上大约 15 秒内完成了 10000 条记录。其中至少有 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
Run Code Online (Sandbox Code Playgroud)

如果有一些 API 可以让我以这种方式进行快速插入,我愿意求助于 C/C++。但是我好像找不到。不可能是 Application.ImportXML 正在使用未记录的 API,是吗?

Han*_*sUp 4

除非您必须使用 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
Run Code Online (Sandbox Code Playgroud)

这是我使用的 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
Run Code Online (Sandbox Code Playgroud)

  • 另请注意:如果您从另一个进程(如 C 程序)与 MSACCESS.EXE 进程进行通信,由于 COM 编组,上述方法会很慢,但如果您在 MSACCESS.EXE 进程(如 Access)内运行,则速度很快VBA)。您可以使用 CreateObject("DAO.DBEngine.36").OpenDatabase() 来解决速度缓慢的问题,它会在当前进程内创建 DAO 实例并避免编组。差异约为 30 倍加速!在 C 程序中,这对我来说意味着每秒 800 次插入,而每秒 24000 次插入。 (2认同)