Liebe Gäste des Forums
Danke, dass ihr euch hier auf dem inoffiziellen Windev-Forum umschaut. Hier werden Tipps und Hinweise zu der von PC-Soft angebotenen Software Windev besprochen.
Windev ist eine leistungsstarke, sehr umfangreiche Entwicklersoftware für Webseiten, Handys und Rechner verschiedener Betriebssysteme. Mehr unter http://www.windev.com

Queryergebnisse (schnell) durchlaufen

Alle Themen rund um die Erstellung von Programmen
Antworten
Magic
Member
Beiträge: 51
Registriert: 2. September 2011, 13:48

Queryergebnisse (schnell) durchlaufen

Beitrag von Magic » 25. September 2013, 09:00

Hi,

ich arbeite mich zwar erst gerade in WinDev ein und habe schon das erste Projekt vorliegen mit dem Ziel Performanceoptimierung.
Dank Trace() und Zeitmessung habe ich die Engstellen im Projekt identifiziert, kann sie aber (noch) nicht beseitigen.
Eine diese Engstelle ist das Durchlaufen eines Querys.

Mit HExecuteQuery(...) werden Daten gelesen. Diese Abfrage habe ich schon soweit optimiert, dass nur noch Sekundenbruchteile nötig sind um das Ergebnis zu haben.
Dann wird der/die/das (was ist denn hier eigentlich richtig?) durchlaufen um Daten in einem Scheduler control anzuzeigen.

Ursprünglich wurde das Query mit der Anweisung:

Code: Alles auswählen

for ALL QRY_Abwesenheit
   ...
end
durchlaufen. Und obwohl die Anzahl der Datensätze gering ist (auch mal nur ein) Dauert es unheimlich lange bis das Ende erreicht ist.

Nun hatte ich probiert das Query über eine FOR Schliefe zu durchlaufen. Dafür brauche ich aber die Anzahl der Datensätze im Query. Mit Hilfe der Funktion HNbRec(...) und als Alternative auch mal mit HLast(...) und HRecNum(...) habe ich dann die Anzahl ermitteln wollen. Ergebnis alle "H"-Funktionen die ich auf das Query ausführe, dauern unheimlich lange. Unzumutbar lange.

Ich habe auch schon unterschiedliche Variationen mit LOOP und WHILE probiert. Die Schleifen sind dann nicht das Problem, aber dann z.B. das Lesen des nächsten Datensatzes mit HReadNext(...)

Meine Frage für den nächsten Versuch:
- Welche Möglichkeit habe ich die Anzahl der Datensätze eines Querys zu ermitteln, außer mit den genannten Funktionen HNbRec(...), HLast(...) und HRecNum(...)?
- Und ist es möglich ein Query in eine Schliefe durchzulaufen (FOR = 1 TO nAnzahlDatensaetze) ohne den nächsten Daten mit HReadNext(...) lesen zu müssen? D.h. direkt den Datensatz zu adressieren (~wie ein Array) mit Query?

Welche sonstigen Ideen habt Ihr um diesen Flaschenhals zu entschärfen?
Gruß,
Magic

Magic
Member
Beiträge: 51
Registriert: 2. September 2011, 13:48

Re: Queryergebnisse (schnell) durchlafen

Beitrag von Magic » 25. September 2013, 09:33

Ich zeige Euch welche Varianten ich bereits ausprobiert habe;

Code: Alles auswählen

tStartTime = Now()
for ALL QRY_Abwesenheit
	show_Abwesenheit(QRY_Abwesenheit.PS_NR,...)
end
Trace( "Abwesenheitsdaten malen (FOR ALL original): " + TimeDifference( tStartTime, Now() ) / 100 )

Code: Alles auswählen

tStartTime = Now()
nAnzahlDatensaetze = HNbRec( QRY_Abwesenheit )
Trace( "Anzahl Datensätze (" + nAnzahlDatensaetze + ") ermittlen mit HNbRec(...): " + TimeDifference( tStartTime, Now() ) / 100 )
tStartTime = Now()
IF nAnzahlDatensaetze > 0 THEN
	HReadFirst(QRY_Abwesenheit)
	FOR i = 1 TO nAnzahlDatensaetze
		show_Abwesenheit(QRY_Abwesenheit.PS_NR,...)	
		HReadNext(QRY_Abwesenheit)	
	END
END
Trace( "Abwesenheitsdaten malen (FOR i Variante): " + TimeDifference( tStartTime, Now() ) / 100 )

Code: Alles auswählen

tStartTime = Now()
HReadFirst(QRY_Abwesenheit)
WHILE HOut(QRY_Abwesenheit) = False
	show_Abwesenheit(QRY_Abwesenheit.PS_NR,...)	
	HReadNext(QRY_Abwesenheit)	
END
Trace( "Abwesenheitsdaten malen (WHILE HOut(..) Variante): " + TimeDifference( tStartTime, Now() ) / 100 )

Code: Alles auswählen

tStartTime = Now()
HReadFirst(QRY_Abwesenheit)
LOOP
	IF HOut()=True THEN BREAK
	show_Abwesenheit(QRY_Abwesenheit.PS_NR,...)	
    HReadNext(QRY_Abwesenheit)		
END
Trace( "Abwesenheitsdaten malen (LOOP Variante): " + TimeDifference( tStartTime, Now() ) / 100 )

Code: Alles auswählen

tStartTime = Now()
FOR EACH QRY_Abwesenheit 
	IF HOut()=True THEN BREAK	
	show_Abwesenheit(QRY_Abwesenheit.PS_NR,...)
END
Trace( "Abwesenheitsdaten malen (FOR EACH Variante): " + TimeDifference( tStartTime, Now() ) / 100 )
Die Zeitmessung ist bei allem Varianten in etwa gleich. Und vor allem zu lang.
Es ist definitiv der erste Zugriff auf das Query, der so lange dauert. Egal ob es das HNbRec(...) oder HReadFirst(..), etc. ist.
Was kann man dagegen machen?
Gruß,
Magic