Große Tabelle in Array einlesen ...
Moderator: Moderatoren
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Große Tabelle in Array einlesen ...
Mahlzeit ...
ich bin mir nicht sicher, zumindest finde ich im Forum nichts, ob ich die Frage nicht schon gestellt habe, wenn ja -> sorry ...
Ich muß eine große Tabelle (Rechnungen 50.000 Datensätze) für Browse in ein Array einlesen. Ich mache das jetzt mir "DO WHILE ! EOF()" und entsprechenden Filterbedingungen. Das dauert etwa 25 Sek.auf einem lokalen Rechner. Im Netz können es da schon mal 50 Sek werden. Gibts da ne Möglichkeit das schneller zu machen?
ich bin mir nicht sicher, zumindest finde ich im Forum nichts, ob ich die Frage nicht schon gestellt habe, wenn ja -> sorry ...
Ich muß eine große Tabelle (Rechnungen 50.000 Datensätze) für Browse in ein Array einlesen. Ich mache das jetzt mir "DO WHILE ! EOF()" und entsprechenden Filterbedingungen. Das dauert etwa 25 Sek.auf einem lokalen Rechner. Im Netz können es da schon mal 50 Sek werden. Gibts da ne Möglichkeit das schneller zu machen?
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- Manfred
- Foren-Administrator
- Beiträge: 21225
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 70 Mal
Re: Große Tabelle in Array einlesen ...
auf jeden Fall schon mal auf DbEval() aumstellen. Und was heißt Filterbedingungen? Wirklich Filter? geht es nicht auch über Scope?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15707
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 71 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Große Tabelle in Array einlesen ...
SET FILTER nicht mit Index mixen ...
Am schnellsten ist
1. Seek auf ersten Treffer, falls das möglich ist, ansonsten ersten möglichen Indextreffer
2. DBEVAL() ... mit REST (sonst fängt er von Anfang an), FOR Bedingung, wenn möglich ENDE Codeblock
3. Wenn möglich muss ein Index die möglichen Treffer stark beschränken
Am schnellsten ist
1. Seek auf ersten Treffer, falls das möglich ist, ansonsten ersten möglichen Indextreffer
2. DBEVAL() ... mit REST (sonst fängt er von Anfang an), FOR Bedingung, wenn möglich ENDE Codeblock
3. Wenn möglich muss ein Index die möglichen Treffer stark beschränken
Gruß
Hubert
Hubert
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Große Tabelle in Array einlesen ...
Ein SELECT INTO mit einem Array aus DataObjects als Ziel dürfte sehr schnell sein.
Herzlich,
Tom
Tom
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Große Tabelle in Array einlesen ...
erst mal Danke!
ich habe noch vergessen zu sagen, daß ich in der Schleife noch eine Function aufrufe, in der ich für jede Rechnung verschiedene Berechnungen mache. Aus dieser Function bekomme ich ein Array zurück.
Wie müßte denn der Syntax für DbEval sein? Habe ich noch nie verwendet. Aus der Doku werde ich nicht schlau
ich habe noch vergessen zu sagen, daß ich in der Schleife noch eine Function aufrufe, in der ich für jede Rechnung verschiedene Berechnungen mache. Aus dieser Function bekomme ich ein Array zurück.
Wie müßte denn der Syntax für DbEval sein? Habe ich noch nie verwendet. Aus der Doku werde ich nicht schlau
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- Martin Altmann
- Foren-Administrator
- Beiträge: 16555
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: Große Tabelle in Array einlesen ...
Wolfgang,
der einfachste Weg ist:
Da siehst Du auch, wie eine Funktion genutzt werden kann (in meinem Fall liefert sie einen String zurück).
Je nach Menge der Daten (Anzahl Sätze und Felder) kann es schneller sein, das Array vorher in der benötigten Länge anzulegen und dann gezielt zu befüllen:
Viele Grüße,
Martin
der einfachste Weg ist:
Code: Alles auswählen
mitglabt->( dbeval( {|| aadd( aAlleAbt, { AID, " " + strzero( EINTRITTM, 2 ) + "/" + alltrim( str( EINTRITTJ ) ) + iif( AUSTRITTJ > 0, " " + strzero( AUSTRITTM, 2 ) + "/" + alltrim( str( AUSTRITTJ ) ), "" ), recno() } ), iif( ( AUSTRITTM == 0 ) .and. ( AUSTRITTJ == 0 ), nAnz++, ) } ) )
Je nach Menge der Daten (Anzahl Sätze und Felder) kann es schneller sein, das Array vorher in der benötigten Länge anzulegen und dann gezielt zu befüllen:
Code: Alles auswählen
::aMITGLgel := array( 50000 )
nI := 0
mitglied->( DbGoTop() )
mitglied->( dbeval( {|| ::aMITGLgel[ ++nI ] := { MID, alltrim( alltrim( VORNAME ) + " " + alltrim( NAME ) ), GELOESCHT, AKTIVMITGL, alltrim( alltrim( NAME ) + ", " + alltrim( VORNAME ) ) } }, {|| ( .NOT. AKTIVMITGL ) .OR. GELOESCHT } ) )
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Große Tabelle in Array einlesen ...
vielen Dank. Das hilft mir schon mal weiter ...
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- brandelh
- Foren-Moderator
- Beiträge: 15707
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 71 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Große Tabelle in Array einlesen ...
Je nach Art der gesuchten Daten kann man mit der richtigen Sortierung viel Zeit sparen.
Das Beispiel von Martin, geht die komplette Datei durch, manchmal muss man das !
Wenn man aber z.B. nur die Adressen in einem Postleitzahlbereich anschreiben will, setzt man den Index auf die Postleitzahl,
DBSEEK() auf den ersten möglichen Treffer
die bWhileCondition ... auf die Abbruchbedingung
und ganz wichtig, den letzten Parameter lRest auf .t.
Bei ein paar Tausend Sätzen spielt das auf einer SSD keine Rolle, aber wenn man nur 10% von 500.000 Sätzen durchsuchen muss ist das schon ein Unterschied.
Natürlich sollte man aber auch TOMs Select mal testen (hab ich keine Erfahrung mit),
insbesondere bei dem Durchsuchen der ganzen Datei könnte da viel Potential liegen, wenn man SQL kann und die Umsetzung gut war.
Vor Jahren hatte ich mal einen Vergleich mit DO WHILE ! EOF() und DBEVEAL() mit gleichem Suchbegriff und gleicher Datei war DBEVAL() etwa 1/3 schneller ...
Das Beispiel von Martin, geht die komplette Datei durch, manchmal muss man das !
Wenn man aber z.B. nur die Adressen in einem Postleitzahlbereich anschreiben will, setzt man den Index auf die Postleitzahl,
DBSEEK() auf den ersten möglichen Treffer
die bWhileCondition ... auf die Abbruchbedingung
und ganz wichtig, den letzten Parameter lRest auf .t.
Code: Alles auswählen
DbEval( <bBlock>, ;
[<bForCondition>], ;
[<bWhileCondition>], ;
[<nCount>], ;
[<xRecordID>], ;
[<lRest>] ) --> NIL
Natürlich sollte man aber auch TOMs Select mal testen (hab ich keine Erfahrung mit),
insbesondere bei dem Durchsuchen der ganzen Datei könnte da viel Potential liegen, wenn man SQL kann und die Umsetzung gut war.
Vor Jahren hatte ich mal einen Vergleich mit DO WHILE ! EOF() und DBEVEAL() mit gleichem Suchbegriff und gleicher Datei war DBEVAL() etwa 1/3 schneller ...
Gruß
Hubert
Hubert
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Große Tabelle in Array einlesen ...
So, habe jetzt mal alle Möglichkeiten durchgespielt (außer Tom). Mit Abstand am Schnellsten ist (20 Sek) ist:
Mit 70 Sek. ist DBEVAL() am langsamtsen
wobei Index auf Jahr (aXbp[4]:getData())
Code: Alles auswählen
IF N1->(DBSEEK(aXbp[4]:getData()))
DO WHILE ! EOF()
....
N1->(DBSKIP())
ENDDO
Code: Alles auswählen
n1->( DBEVAL ({ || AADD(aARR2, {n1->rech_jahr, n1->rech_nr, ...) } )}, {|| aXbp[4]:getData() == "2020"},,,,.T.))
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- Manfred
- Foren-Administrator
- Beiträge: 21225
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 70 Mal
Re: Große Tabelle in Array einlesen ...
janu,
hast Du mal geprüft, wieviel Sätze Du mit dem Dbseek() überspringst, die DBEval zusätzlich durchlaufen mußt? Ich sehe nämich nirgendwo, dass Du da auch ein Dbseek vorher machst. Du sagst zwar schön es soll nur den rest machen, aber am Anfang stehend ist alles folgende der rest.
hast Du mal geprüft, wieviel Sätze Du mit dem Dbseek() überspringst, die DBEval zusätzlich durchlaufen mußt? Ich sehe nämich nirgendwo, dass Du da auch ein Dbseek vorher machst. Du sagst zwar schön es soll nur den rest machen, aber am Anfang stehend ist alles folgende der rest.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15707
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 71 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Große Tabelle in Array einlesen ...
Bei Gelegenheit probiere ich das mal MIT Tom durch ... ich kanns nicht so recht glauben, dass DBEVAL() langsamer ist, wenn beide die gleiche Arbeit haben (besonders interne Funktionsaufrufe und Array Zuweisungen)
Gruß
Hubert
Hubert
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Große Tabelle in Array einlesen ...
Hast recht. Wird aber deswegen auch nicht schneller als DO WHILE !EOF() mit Index und DBSEEK() auf den ersten Satz. Problem ist auch, daß ich bei jedem Satz mehrere Werte per Funktion berechnen muß, die in einem Array zurückgegeben werden und dann in das erste Array mit einfliesen. Ich wüßte nicht, wie ich diese Logik mit DBEVAL() realisieren könnte.
So z.B.
So z.B.
Code: Alles auswählen
DBSEEk(..)
Do While ! eof()
aArray := Funktion(berechne)
IF aArray[1] > 0
AADD(aArray2 ( x1,x2, aArray[1], aArray[2], aArray[3], ...)
ENDIF
DBSKIP()
ENDDO
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- Manfred
- Foren-Administrator
- Beiträge: 21225
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 70 Mal
Re: Große Tabelle in Array einlesen ...
Code: Alles auswählen
Dbseek()
DbEval({|| aArray := Funktion(berechne),IF(aArray[1]>0,AADD(aArray2 ( x1,x2, aArray[1], aArray[2], aArray[3], ...),NIL)},,,,.T.)
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Wolfgang_B
- Rekursionen-Architekt
- Beiträge: 486
- Registriert: Do, 14. Jun 2007 18:22
- Wohnort: 94065 Waldkirchen
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 5 Mal
Re: Große Tabelle in Array einlesen ...
Manfred, funktioniert. Aber insgesamt nicht wesentlich schneller als mit DO WHILE ...
An alle Danke!
An alle Danke!
Beste Grüße
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Wolfgang
Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
- Martin Altmann
- Foren-Administrator
- Beiträge: 16555
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: Große Tabelle in Array einlesen ...
Wolfgang,
hast du mal versucht, das Array vorab in der benötigten Größe anzulegen und in DbEval() nicht mit Aadd() zu arbeiten?
Viele Grüße,
Martin
hast du mal versucht, das Array vorab in der benötigten Größe anzulegen und in DbEval() nicht mit Aadd() zu arbeiten?
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- brandelh
- Foren-Moderator
- Beiträge: 15707
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 71 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Große Tabelle in Array einlesen ...
DBEVAL() kann nur schneller sein weil sie intern bessere Methoden für den Schleifendurchlauf haben (optimierter C-Code),
wenn aber die Berechnungen selbst etwas dauern, kann das so viel mehr Zeit kosten, dass der minimale Vorteil aufgebraucht wird.
Es kommt natürlich auch auf verständlichen Code an und da ziehe ich oft das langsamere do while einer komplexen DBEVAL() Zeile vor ...
Hauptsache es ist schnell genug
wenn aber die Berechnungen selbst etwas dauern, kann das so viel mehr Zeit kosten, dass der minimale Vorteil aufgebraucht wird.
Es kommt natürlich auch auf verständlichen Code an und da ziehe ich oft das langsamere do while einer komplexen DBEVAL() Zeile vor ...
Hauptsache es ist schnell genug
Gruß
Hubert
Hubert
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Große Tabelle in Array einlesen ...
wie viele Datensätze hast du das du 20 Sec. brauchstWolfgang_B hat geschrieben: ↑Mo, 14. Dez 2020 12:08 So, habe jetzt mal alle Möglichkeiten durchgespielt (außer Tom). Mit Abstand am Schnellsten ist (20 Sek) ist:
...
wobei Index auf Jahr (aXbp[4]:getData())
Code: Alles auswählen
IF N1->(DBSEEK(aXbp[4]:getData()))
{|| aXbp[4]:getData() == "2020"}
damit werden nur die betreffende Daten geSKIPt
---
sollte der Begriff "im" Text Feld stehen kann man OrdWildSeek() verwenden
gruss by OHR
Jimmy
Jimmy
- Jan
- Marvin
- Beiträge: 14662
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: Große Tabelle in Array einlesen ...
Jimmy,
Jan
Und er erwähnte, das da auch noch Berechnungen zu jedem Satz gehören.Wolfgang_B hat geschrieben: ↑So, 13. Dez 2020 12:04Ich muß eine große Tabelle (Rechnungen 50.000 Datensätze) für Browse in ein Array einlesen.
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.