ADO 记录集批量检索 运行 速度过慢
ADO RecordSet Batch Retrievals Running Excessively Slowly
我正在使用 Excel-VBA 通过 ADO 连接到 MS-Access 数据库。它正在执行我在 Access 数据库中的存储过程。大约有 900 条记录返回了 13 个字段。我正在使用以下 VBA 代码:
Dim RS As ADODB.Recordset
Call OpenDatabase 'Subroutine that opens an ADO connection: DatabaseName
Set RS = DatabaseName.Execute("SELECT * FROM My_Procedure") 'This DOES return a recordset
Do While Not RS.EOF
Debug.Print RS(0)
RS.MoveNext
Loop
Call CloseDatabase 'Another sub
数据库连接在这里:
Sub OpenDatabase
Dim ConnString as String
Set DB = New ADODB.Connection
ConnString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & My_DB_Path & "; Persist Security Info=False;"
With DB
.ConnectionString = ConnString
.ConnectionTimeout = 10
.Open
End With
End Sub
这里是带有通用名称的查询:
SELECT Col1, Col2, Col3,
(SELECT Col4 FROM t2 where t2.Col1 = t1.Col1 AND t2.Col2 = t1.Col2 and Col4 IS NOT NULL) As Col4,
(SELECT Col5 FROM t2 where t2.Col1 = t1.Col1 AND t2.Col2 = t1.Col2 and Col5 IS NOT NULL) As Col5,
... (Same through Col13)
FROM t1
在存储过程中,字段 1、2 和 3 都非常简单,一切都非常快速。然而,不幸的是,字段 #4-13 都是更复杂的 select 语句,这似乎是问题的一部分
这并不是一个更好的方法,但在 MS-Access 的限制内,这是我必须做的,以便按照我需要的方式格式化数据。
当我在 Access 中 运行 此过程时,可能需要 15-20 秒来计算和显示 DataSheet 视图中的所有内容。当我 运行 上面的 VBA 代码时,Do 循环大约需要 0.45 秒来打印所有 900 行 RS(0,1,2),但是 Debug.Print RS(3- >12),每个字段需要超过 280 秒。我怀疑每次我在 VBA 中请求它时它都在重新计算所有这些嵌入式子查询,但我不知道为什么。
理想情况下,我希望访问 运行 过程并生成结果,我只是将每条记录拉入一个 VBA 变量以供进一步处理。关于如何加快此检索过程的任何想法?
编辑以添加示例数据:
这是查询所处理的数据的一般化示例,以及完成后应该是什么样子。输入如下:
Col1|Col2|Col3|Col4|Col5|...
A |01 |X | |
A |01 | |Y |
A |02 |X | |
A |02 | |Y |
B |01 | |X |
B |02 | |X |
B |02 |Y | |
B |02 | | |Z
输出如下:
Col1|Col2|Col3|Col4|Col5|...
A |01 |X |Y |
A |02 |X |Y |
B |01 | |X |
B |02 |Y |X |Z
根据您当前的示例数据和所需的结果,您当然可以优化查询。现在,您 运行 9 个单独的子查询从每个相应的列中检索非空值。简单地说,运行 聚合查询使用 MAX()
列,3 - 13,分组在前两列:
SELECT Col1, Col2, Max(Col3) As C3, Max(Col4) As C4, Max(Col5) As C5, ...
Max(Col13) As C13
FROM t1
GROUP BY Col1, Col2
我正在使用 Excel-VBA 通过 ADO 连接到 MS-Access 数据库。它正在执行我在 Access 数据库中的存储过程。大约有 900 条记录返回了 13 个字段。我正在使用以下 VBA 代码:
Dim RS As ADODB.Recordset
Call OpenDatabase 'Subroutine that opens an ADO connection: DatabaseName
Set RS = DatabaseName.Execute("SELECT * FROM My_Procedure") 'This DOES return a recordset
Do While Not RS.EOF
Debug.Print RS(0)
RS.MoveNext
Loop
Call CloseDatabase 'Another sub
数据库连接在这里:
Sub OpenDatabase
Dim ConnString as String
Set DB = New ADODB.Connection
ConnString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & My_DB_Path & "; Persist Security Info=False;"
With DB
.ConnectionString = ConnString
.ConnectionTimeout = 10
.Open
End With
End Sub
这里是带有通用名称的查询:
SELECT Col1, Col2, Col3,
(SELECT Col4 FROM t2 where t2.Col1 = t1.Col1 AND t2.Col2 = t1.Col2 and Col4 IS NOT NULL) As Col4,
(SELECT Col5 FROM t2 where t2.Col1 = t1.Col1 AND t2.Col2 = t1.Col2 and Col5 IS NOT NULL) As Col5,
... (Same through Col13)
FROM t1
在存储过程中,字段 1、2 和 3 都非常简单,一切都非常快速。然而,不幸的是,字段 #4-13 都是更复杂的 select 语句,这似乎是问题的一部分
这并不是一个更好的方法,但在 MS-Access 的限制内,这是我必须做的,以便按照我需要的方式格式化数据。
当我在 Access 中 运行 此过程时,可能需要 15-20 秒来计算和显示 DataSheet 视图中的所有内容。当我 运行 上面的 VBA 代码时,Do 循环大约需要 0.45 秒来打印所有 900 行 RS(0,1,2),但是 Debug.Print RS(3- >12),每个字段需要超过 280 秒。我怀疑每次我在 VBA 中请求它时它都在重新计算所有这些嵌入式子查询,但我不知道为什么。
理想情况下,我希望访问 运行 过程并生成结果,我只是将每条记录拉入一个 VBA 变量以供进一步处理。关于如何加快此检索过程的任何想法?
编辑以添加示例数据:
这是查询所处理的数据的一般化示例,以及完成后应该是什么样子。输入如下:
Col1|Col2|Col3|Col4|Col5|...
A |01 |X | |
A |01 | |Y |
A |02 |X | |
A |02 | |Y |
B |01 | |X |
B |02 | |X |
B |02 |Y | |
B |02 | | |Z
输出如下:
Col1|Col2|Col3|Col4|Col5|...
A |01 |X |Y |
A |02 |X |Y |
B |01 | |X |
B |02 |Y |X |Z
根据您当前的示例数据和所需的结果,您当然可以优化查询。现在,您 运行 9 个单独的子查询从每个相应的列中检索非空值。简单地说,运行 聚合查询使用 MAX()
列,3 - 13,分组在前两列:
SELECT Col1, Col2, Max(Col3) As C3, Max(Col4) As C4, Max(Col5) As C5, ...
Max(Col13) As C13
FROM t1
GROUP BY Col1, Col2