Vba 为什么记录集;“移动最后一个”;使用更少记录的记录集需要更长的时间?

Vba 为什么记录集;“移动最后一个”;使用更少记录的记录集需要更长的时间?,vba,ms-access,Vba,Ms Access,我调用了一个函数来提取某些字段的记录: Public Function fun_rstlast(str_input As String, str_field As String) As Variant Set rst = dbcOC.OpenRecordset(str_input, dbOpenSnapshot) rst.MoveLast fun_rstlast = rst.Fields(str_field) rst.Close Set rst =

我调用了一个函数来提取某些字段的记录:

Public Function fun_rstlast(str_input As String, str_field As String) As Variant

    Set rst = dbcOC.OpenRecordset(str_input, dbOpenSnapshot)
    rst.MoveLast

    fun_rstlast = rst.Fields(str_field)

    rst.Close
    Set rst = Nothing

End Function
它位于一系列循环中,因此从两组相同的表中提取相同的记录序列(是的,我知道,但我现在想保持这种方式)。令人恼火的是,出于某种原因,从第一组表运行函数所需的时间是从第二组表运行函数所需时间的10倍。我看了一下记录集,来自更快表的记录集实际上是2倍大

下面是执行循环的代码部分:

            Set col = New Collection

            str_DATE_G = "DATE_S"

            arr_field(1) = "DATE_S"
            arr_field(2) = "LATITUDE_T"
            arr_field(3) = "LONGITUDE_T"

            For r = 1 To UBound(arr_ID)

                lng_ID = arr_ID(r)

                For f = 1 To UBound(arr_field)

                    str_field = arr_field(f)

                    'debug.Print "str_field: " & str_field

                    ' Create query string
                    str_input = "SELECT * " _
                        & " FROM (tbl_G_stats_" & tour & " INNER JOIN tbl_G_ov_" & tour _
                        & " ON tbl_G_stats_" & tour & ".PK_G = tbl_G_ov_" & tour & ".PK_G)" _
                        & " INNER JOIN tours_" & tour & " ON tbl_G_ov_" & tour & ".ID_T = tours_" & tour & ".ID_T" _
                        & " WHERE Clng(" & str_DATE_G & ") < " & lng_DATE_G _
                        & " AND tbl_G_stats_" & tour & "." & str_ID_A & " = " & lng_ID

                    secs1 = Timer()

                    var_rstlast = fun_rstlast(str_input, str_field)

                    secs2 = Timer()

                    'debug.Print "var_rstlast: " & var_rstlast

                    Debug.Print "Timer: " & lng_ID & " " & str_field & " " & (secs2 - secs1) * 1000

                    col.Add var_rstlast

                Next f

            Next r
Set col=新集合
str_DATE_G=“日期”
arr_字段(1)=“日期”
arr_字段(2)=“纬度”
arr_字段(3)=“经度”
对于r=1至UBound(arr_ID)
液化天然气管道ID=arr管道ID(r)
对于f=1至uBond(arr_字段)
str_字段=arr_字段(f)
'debug.Print“str_字段:”&str_字段
'创建查询字符串
str_input=“选择*”_
&“FROM(tbl_G_统计数据)&tour和“内部连接tbl_G_统计数据”&tour_
&“关于tbl_G_stats_”&tour&“.PK_G=tbl_G_ov_”&tour&.PK_G)”_
&“内部加入tours”&tours&“在tbl&tours&.ID\u T=tours&.ID\T上”&tours&.ID\T”_
&其中Clng(“&str\U DATE\U G&”<”&lng\U DATE\G_
&“和tbl_G_stats_”&tour&“&str_ID_A&“=”&lng_ID
secs1=计时器()
var\u rstlast=fun\u rstlast(str\u输入,str\u字段)
secs2=计时器()
'debug.Print“var\u rstlast:&var\u rstlast
调试。打印“计时器:&lng\u ID&&str\u字段&&(secs2-secs1)*1000
列添加var_rstlast
下一个f
下一个r
后面还有一个循环,它在两组表之间交替出现(
tour

值得一提的是,我调查了两个表的索引和数据类型,所有内容都是相同的


你知道为什么会发生这种情况吗?

导致性能变化的最常见原因是表/索引碎片

要修复Access中的表碎片,可以执行压缩和修复。Compact&repair将所有表作为一个整体移动到一个新位置,然后删除旧表,在过程中删除所有表碎片,通常也避免文件碎片

在插入文本数据后更新文本数据(因为文本数据可能比原始数据长)以及在主键字段中手动插入数据时,通常会发生表碎片。不过,原因还有很多


如果经常遇到表碎片,Access会在“数据库设置”菜单中提供“关闭时压缩”设置。但是,关闭数据库时会有很大的延迟。

导致性能变化的最常见原因是表/索引碎片

要修复Access中的表碎片,可以执行压缩和修复。Compact&repair将所有表作为一个整体移动到一个新位置,然后删除旧表,在过程中删除所有表碎片,通常也避免文件碎片

在插入文本数据后更新文本数据(因为文本数据可能比原始数据长)以及在主键字段中手动插入数据时,通常会发生表碎片。不过,原因还有很多


如果经常遇到表碎片,Access会在“数据库设置”菜单中提供“关闭时压缩”设置。但是,关闭数据库时会出现很大的延迟。

这可能是由于许多原因造成的,最常见的原因是表碎片,您可以通过压缩和修复来修复。这个问题是不可复制的。先生,你真棒:-)C&R解决了它。两件事:我)我假设这是一个数据库,它等同于打开和再打开?ii)坚持这个作为答案,获得声誉!!请注意,
str_输入
不依赖于
str_字段
,这意味着查询在每次调用时都返回相同的结果。您可以将该部分从j循环的
中移出……我是说f
循环的
。@Jossy我已经添加了一个快速解释作为答案。如果你想知道更多,你可以在谷歌上搜索索引碎片,并遇到很多关于它的SQLServer文章。Access有点类似,但不幸的是,它不允许我们在没有完全压缩和修复的情况下重建索引,也不允许我们指定填充因子或获取碎片统计信息。这可能是由于许多原因造成的,最常见的原因是表碎片,您可以使用压缩和修复来修复。这个问题是不可复制的。先生,你真棒:-)C&R解决了它。两件事:我)我假设这是一个数据库,它等同于打开和再打开?ii)坚持这个作为答案,获得声誉!!请注意,
str_输入
不依赖于
str_字段
,这意味着查询在每次调用时都返回相同的结果。您可以将该部分从j
循环的
中移出……我是说f
循环的
。@Jossy我已经添加了一个快速解释作为答案。如果你想知道更多,你可以在谷歌上搜索索引碎片,并遇到很多关于它的SQLServer文章。Access有点类似,但不幸的是,它不允许我们在没有完全压缩和修复的情况下重建索引,也不允许我们指定填充因子或获取碎片统计信息。