gpt4 book ai didi

vb6 - 访问 ADO 记录集中字段值的最有效方法是什么?

转载 作者:行者123 更新时间:2023-12-02 05:37:25 24 4
gpt4 key购买 nike

我面前有一个 VB6 应用程序,它通过 ADO 访问 Sql 数据库。

检索记录集时,应用程序使用 Bang (!) 运算符来访问记录集中的字段,例如 RS!OrderId。

虽然我知道这种做法,但我从未真正使用过它(除非我很懒),我也没有使用过 RS("OrderId") 因为我一直(或通常)使用完全限定的方法(例如 RS.fields("OrderId").value。甚至可以使用 .Item 属性进一步扩展它。)

两者都返回完全相同的值,其中一个比另一个更短。

我坚持使用这种方法的原因是,在遥远的过去的某个时候,我相信我被告知完全限定该字段的性能更高,因为代码必须翻译每次出现的 !运营商为其完全合格的姐妹。但是,那 !运算符减少了输入,从而减少了开发时间。

我似乎还记得!因为 ADO 将在未来某个时候被弃用。但它似乎仍然存在于代码中,我只是想知道哪种方法被视为最佳实践以及哪种方法比另一种方法表现更好。

最佳答案

我已经彻底测试了 VB6 和 ADO 在我的应用程序中的使用性能。从记录集中获取数据的绝对最快方法是使用 FIELD 对象。返回大量行时,您会注意到性能上的巨大差异。以下是我的应用程序中的一段代码(简化以突出显示字段对象的正确使用)。

Dim fMinLongitude As ADODB.Field
Dim fMinLatitude As ADODB.Field
Dim fMaxLongitude As ADODB.Field
Dim fMaxLatitude As ADODB.Field
Dim fStreetCount As ADODB.Field

If RS.RecordCount = 0 Then
Exit Sub
End If

Set fMinLongitude = RS.Fields.Item("MinLongitude")
Set fMinLatitude = RS.Fields.Item("MinLatitude")
Set fMaxLongitude = RS.Fields.Item("MaxLongitude")
Set fMaxLatitude = RS.Fields.Item("MaxLatitude")
Set fStreetCount = RS.Fields.Item("StreetCount")

While Not RS.EOF
LineGridCount = LineGridCount + 1
With LineGrid(LineGridCount)
.MinLongitude = fMinLongitude.Value
.MaxLongitude = fMaxLongitude.Value
.MinLatitude = fMinLatitude.Value
.MaxLatitude = fMaxLatitude.Value
End With
RS.MoveNext

Wend

RS.Close
Set RS = Nothing

请注意,我为 SQL Server 存储过程返回的 5 列设置了字段对象。然后我在循环内使用它们。当您执行 RS.MoveNext 时,它会影响字段对象。

使用上面显示的代码,我可以在不到 1 秒的时间内将 26,000 行加载到我的用户定义类型中。事实上,运行完代码只花了 0.05 秒。在编译后的应用程序中,速度甚至更快。

如果您不使用字段对象,那么您至少应该使用WITH block 。正如另一篇文章中提到的,使用序数位置比其他替代方法更快(字段方法除外)。如果您计划使用序数位置,那么您应该使用WITH block 。例如:

With RS.Fields
ID = .Item(0).Value
Name = .Item(1).Value
EyeColor = .Item(2).Value
End With

使用 with block 很好,因为它减少了输入量,同时加快了代码的执行速度。出现这种性能提升是因为 VB 可以设置一次指向字段对象的指针,然后在每次调用字段对象时重用该指针。

顺便说一句...我不喜欢“少打字”的说法。我经常发现性能更好的代码也是更复杂的代码。借助 VB6 的智能感知,额外的输入也不再那么重要。

RS("FieldName") 为 15 个字符。
我已经养成了这样的习惯: r s (点) f (点) i (左括号) (引号) FieldName (引号) (右括号) (点) v。这是 6 次额外的按键,以充分利用合格的方法。

使用 with block 方法,将是 (dot) i (左括号) (quote) FieldName (quote) (右括号) (dot) v,即 17 个按键。

在这种情况下,一个好习惯只需付出很少的努力,就能通过性能更好的代码获得巨大的返回。

我刚刚做了一些性能测试。以下测试使用客户端游标,这意味着查询返回的所有数据都将复制到客户端计算机并存储在记录集对象中。

我用于性能测试的代码是这样的:

Private Sub Command1_Click()

Dim DB As ADODB.Connection
Dim RS As ADODB.Recordset
Dim Results() As String

Set DB = New ADODB.Connection
DB.ConnectionString = "my connection string here"
DB.CursorLocation = adUseClient
DB.Open

Set RS = New ADODB.Recordset
Call RS.Open("Select * From MapStreetsPoints", DB, adOpenForwardOnly, adLockReadOnly)

Dim Start As Single
Dim FeatureId As Long
Dim PointNumber As Long
Dim Longitude As Single
Dim Latitude As Single
Dim fFeatureId As ADODB.Field
Dim fPointNumber As ADODB.Field
Dim fLongitude As ADODB.Field
Dim fLatitude As ADODB.Field

ReDim Results(5)

RS.MoveFirst
Start = Timer
Do While Not RS.EOF
FeatureId = RS!FeatureId
PointNumber = RS!PointNumber
Longitude = RS!Longitude
Latitude = RS!Latitude
RS.MoveNext
Loop
Results(0) = "Bang Method: " & Format(Timer - Start, "0.000")

RS.MoveFirst
Start = Timer
Do While Not RS.EOF
FeatureId = RS.Fields.Item("FeatureId").Value
PointNumber = RS.Fields.Item("PointNumber").Value
Longitude = RS.Fields.Item("Longitude").Value
Latitude = RS.Fields.Item("Latitude").Value
RS.MoveNext
Loop
Results(1) = "Fully Qualified Name Method: " & Format(Timer - Start, "0.000")

RS.MoveFirst
Start = Timer
Do While Not RS.EOF
FeatureId = RS.Fields.Item(0).Value
PointNumber = RS.Fields.Item(1).Value
Longitude = RS.Fields.Item(2).Value
Latitude = RS.Fields.Item(3).Value
RS.MoveNext
Loop
Results(2) = "Fully Qualified Ordinal Method: " & Format(Timer - Start, "0.000")

RS.MoveFirst
Start = Timer
With RS.Fields
Do While Not RS.EOF
FeatureId = .Item("FeatureId").Value
PointNumber = .Item("PointNumber").Value
Longitude = .Item("Longitude").Value
Latitude = .Item("Latitude").Value
RS.MoveNext
Loop
End With
Results(3) = "With Block Method: " & Format(Timer - Start, "0.000")

RS.MoveFirst
Start = Timer
With RS.Fields
Do While Not RS.EOF
FeatureId = .Item(0).Value
PointNumber = .Item(1).Value
Longitude = .Item(2).Value
Latitude = .Item(3).Value
RS.MoveNext
Loop
End With
Results(4) = "With Block Ordinal Method: " & Format(Timer - Start, "0.000")

RS.MoveFirst
Start = Timer
Set fFeatureId = RS.Fields.Item("FeatureId")
Set fPointNumber = RS.Fields.Item("PointNumber")
Set fLatitude = RS.Fields.Item("Latitude")
Set fLongitude = RS.Fields.Item("Longitude")
Do While Not RS.EOF
FeatureId = fFeatureId.Value
PointNumber = fPointNumber.Value
Longitude = fLongitude.Value
Latitude = fLatitude.Value
RS.MoveNext
Loop
Results(5) = "Field Method: " & Format(Timer - Start, "0.000")

Text1.Text = "Rows = " & RS.RecordCount & vbCrLf & Join(Results, vbCrLf)

End Sub

结果是:

Rows = 2,775,548

Bang Method: 9.441
Fully Qualified Name Method: 9.367
Fully Qualified Ordinal Method: 5.191
With Block Method: 8.527
With Block Ordinal Method: 5.117
Field Method: 4.316

显然,现场方法是赢家。所需时间不到bang法的1/2。另请注意,与字段方法相比,序数方法也具有不错的性能。

关于vb6 - 访问 ADO 记录集中字段值的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21530422/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com