Performance-Frage

29/06/2012 - 07:53 von Lothar Geyer | Report spam
Ich lese Daten aus einer Datenbank. Einige der Felder werden etliche
Male für Berechnungen und Abfragen verwendet. Da die Datenbanken ja ihre
eigenen Darstellungsformat haben: ist es sinnvoll, die Datenbank-Felder
erst in VB-Variablen zu kopieren?

If IsNull(rsv("Zeit1")) And Isnull(rsv("Zeit2)) Then
...
ElseIf IsNull(rsv("Zeit1")) Then
Diff1 = DateDiff("n", rsv("Zeit2"), rsv("Zeit0"))
Else
Diff1 = DateDiff("n", rsv("Zeit2"), rsv("Zeit0"))
Diff2 = DateDiff("n", rsv("ZeiT1"), rsv("Zeit0"))
End If

Oder liefert ADO mit rsv("Zeit0") schon eine VB-Darstellung?

Ich weiß - es handelt sich um Peanuts. Aber bei größeren Recordsets und
komplizierteren Abfragen / Berechnungen könnte das doch schon was ausmachen.

Lothar Geyer
 

Lesen sie die antworten

#1 Schmidt
29/06/2012 - 08:41 | Warnen spam
Am 29.06.2012 07:53, schrieb Lothar Geyer:
Ich lese Daten aus einer Datenbank. Einige der Felder werden etliche
Male für Berechnungen und Abfragen verwendet. Da die Datenbanken ja ihre
eigenen Darstellungsformat haben: ist es sinnvoll, die Datenbank-Felder
erst in VB-Variablen zu kopieren?

If IsNull(rsv("Zeit1")) And Isnull(rsv("Zeit2)) Then
...
ElseIf IsNull(rsv("Zeit1")) Then
Diff1 = DateDiff("n", rsv("Zeit2"), rsv("Zeit0"))
Else
Diff1 = DateDiff("n", rsv("Zeit2"), rsv("Zeit0"))
Diff2 = DateDiff("n", rsv("ZeiT1"), rsv("Zeit0"))
End If

Oder liefert ADO mit rsv("Zeit0") schon eine VB-Darstellung?

Ich weiß - es handelt sich um Peanuts. Aber bei größeren Recordsets und
komplizierteren Abfragen / Berechnungen könnte das doch schon was
ausmachen.



Das tut es mit Sicherheit.

Wenn Du z.B. schreibst:
rsv("Zeit1")

Dann sind da jedesmal eine Menge Methoden-Aufrufe involviert
(inkl. Collection-Zugriff per String-Key).

VB expandiert das ja intern zu:
rsv.Fields.Item("Zeit1").Value

Methoden-Aufrufe:
rsv->Fields
'liefert das Fields-Collection-Objekt von rsv
Fields->Item("Zeit")
'interner Collection-Zugriff per Hash - liefert ein Field-Objekt
Field->Value
'ein weiterer (Property)Call - gibt einen Variant zurück

Also 3 COM-Interface-Calls für *jedes* kleine:
rsv("dies"), rsv("das") ... und einer davon wie gesagt,
zudem auch noch intern mit einem Hash-Lookup belastet.

Erster Schritt wàre also die Feld-Auflösung *vor* dem
Eintritt in Schleifen mit größeren Recordcounts -
das spart 2 COM-calls inkl. des Calls mit dem Hash-Lookup.

Dim FldZeit0 as Field, FldZeit1 as Field
Set FldZeit0 = rsv("Zeit0")
Set FldZeit1 = rsv("Zeit1")

Do Until rsv.EOF
If FldZeit0.Value = ...
If FldZeit1.Value = ...
rsv.MoveNext
Loop

Also nur noch der direkte .Value Property-Call wàre dann
in der Schleife selbst zu leisten.

Wenn Du ein Feld innerhalb des Rs-Loops dann mehr als
nur ein mal mit diesem Value-Call belastest (wie z.B.
in Deinem If-Construct zu sehen...) - dann empfiehlt
sich weiterhin das nur einmalige Ausführen dieses
Value-calls gegen eine entspr. Variable *innerhalb*
des Rs-Loops:

'also Field-Objekt-Auflösung außen
Dim FldZeit0 as Field, FldZeit1 as Field
Set FldZeit0 = rsv("Zeit0")
Set FldZeit1 = rsv("Zeit1")

Dim ValZeit0, ValZeit1 'Variant-Variablen

Do Until rsv.EOF
'Field-Value Auflösung einmalig "innen"
ValZeit0 = FldZeit0.Value
ValZeit1 = FldZeit1.Value

If ValZeit0 = ...
If ValZeit0 = ... AND ValZeit1 = ...
rsv.MoveNext
Loop

Das kann man bei einem größeren Test-RecordCount
(von z.B. 10000 Records) auch mal ganz einfach ausstoppen
mit einem Timer direkt außen um den rs-loop herum -
und die unterschiedlichen Varianten so vergleichen.

T=Timer()
Do Until rsv.EOF
'Field-Value Auflösung einmalig "innen"
ValZeit0 = FldZeit0.Value
ValZeit1 = FldZeit1.Value

If ValZeit0 = ...
If ValZeit0 = ... AND ValZeit1 = ...
rsv.MoveNext
Loop
Debug.Print Timer()-T

Olaf

Ähnliche fragen