Optimierung beim Aufbau von NTX-Dateien

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Optimierung beim Aufbau von NTX-Dateien

Beitrag von Martin Altmann »

Hallo allerseits,
eine Frage an Euch zu der Optimierung.
Wenn ich eine DBF habe mit einem Schlüsselfeld der Länge 6 Zeichen und darüber einen Index mache, so sind die Datensätze ja schön sortiert, die Suche selber aber nicht schnell, da es sich bei dem Index ja nicht um einen wirklichen Baum, sondern eher um einen Baumstamm handelt.
Wenn nun der Feldinhalt des Schlüsselfeldes aus den beiden Jahreszahlen gefolgt von einer aufsteigenden vierstelligen Nummer (die bei jedem neuen Jahr immer wieder bei 0001 beginnt) besteht (Beispiel: 070312), so müßte doch der Index schneller im Zugriff sein, wenn er folgendermaßen aufgebaut ist:

Code: Alles auswählen

INDEX ON LEFT( key, 2 ) + RIGHT( key, 4 )
und noch schneller:

Code: Alles auswählen

INDEX ON LEFT( key, 2 ) + SUBSTR( key, 3, 2 ) + RIGHT( key, 2 )
Oder nicht?

Viele Grüße,
Martin
:grommit:
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.
Krause
UDF-Programmierer
UDF-Programmierer
Beiträge: 52
Registriert: Mo, 08. Jan 2007 8:55
Wohnort: In Thüringen

Beitrag von Krause »

Hallo Martin

den Sachverhalt der Daten im Index "zu drehen / zu verändern" ist meines Erachtens nicht effektiv genug, besser ist es, die Daten schon Indexgerecht abzuspeichern. In Deinem Fall hätte ich die Jahreszahl "07" (z. B. CNTYEAR) , und den Counterwert (z. B. CNTVALUE ) jeweils in ein separates Feld gespeichert. Zusätzlich kann man während des Abspeicherns den Counterwert drehen, zum Bsp. statt „0321“ den Wert in der Form „1230“ abspeichern. Legt man dann noch das Jahr in eine FOR – Bedingung, dann wird die Sache richtig schnell.

Code: Alles auswählen

INDEX ON  CNTVALUE  FOR CNTYEAR="07"
Allerdings bedeutet das, dass man für jedes Jahr einen separaten Index benötigt. Anders sieht die Sache dann aus, wenn man den Index nur für das aktuelle Geschäftsjahr benötigt, dann passt die ganze Sache ...

PS: Existiert eine Firma 10 Jahre sind 90% des Datenbestandes in der Regel uninteressant!

Mit freundlichen Grüßen
Joachim Krause
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo Martin,

so weit ich es verstehe, hast du doch ein Feld mit String von Länge 6.

Nimm doch

Code: Alles auswählen

index on key
und suche dann mit

Code: Alles auswählen

dbseek( alltrim( cWert )+space( 6 - len( alltrim(cWert) ) )
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Joachim und Andreas,
vielen Dank für Eure Antworten - aber darum geht es mir nicht wirklich (oder ich habe mich undeutlich ausgedrückt)!
Es geht darum, den einzelnen Datensätzen eineindeutige Schlüssel zu geben (ihr erinnert Euch vielleicht an meinen entsprechenden Thread...) - da ist es egal, ob etwas 10 Jahre alt ist oder nicht. Ein Eintrag ist solange interessant, bis er 16 Jahr alt ist - dann wird er gelöscht.
Es geht mir auch nicht darum, den Eintrag zu finden. Das geschieht ganz einfach über SEEK cKey, da der gesuchte Schlüssel komplett bekannt ist.
Mir geht es darum, den Eintrag möglichst schnell zu finden!
Es gibt nur eine Indexdatei, die permanent offen ist (aus Performancegründen - es ist ein Webserver, der darauf zugreift. Und es können durchaus mehrere Anfragen parallel eintreffen).
Es geht mir nur darum, den Indexbaum gut auszutarieren, damit möglichst wenig Zugriffe zum Auffinden des Schlüssels nötig sind!
Ein Beispiel:
In der Datenbank stehen "nur" 3890 Datensätze. Der Schlüssel beginnt (noch) bei 070001 und geht demnach bis 073890. Wenn ich jetzt den Index einfach über das ganze Feld gehen lasse, dann sind zum Finden des Schlüssel 073890 somit 3890 Zugriffe auf die Indexdatei nötig.
Nehme ich dagegen den Aufbau, den ich als letztes Beispiel angegeben habe, so sind es nur noch 131 - wenn ich mich jetzt nicht verzählt habe.
Man kann das ganze sicherlich noch weiter treiben, und solch einen Indexausdruck nehmen:

Code: Alles auswählen

INDEX ON LEFT( key, 2 ) + SUBSTR( key, 3, 1 ) + SUBSTR( key, 4, 1 ) + SUBSTR( key, 5, 1 ) + RIGHT( key, 1 )
- dann wären mit dem obigen Beispiel nur noch 24 Zugriffe nötig.
Aber man kann es sicherlich auch übertreiben - oder wie seht ihr das?

Viele Grüße,
Martin
:grommit:
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.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Martin Altmann hat geschrieben:Wenn ich jetzt den Index einfach über das ganze Feld gehen lasse, dann sind zum Finden des Schlüssel 073890 somit 3890 Zugriffe auf die Indexdatei nötig.
Hi Martin,

ich habe das zwar schon öfters hier gelesen, dass NTX kein echter Baum sondern eine indexsequentille Form wäre, aber ich möchte doch mal wissen wo das steht ?

Hast du das mit den 3890 Zugriffen geprüft ?

Meines Wissens war NDX Indexsequentiell.
Clipper hat dann aber auf ein echtes Treeverfahren umgestellt.

Sicher brauchst du keine 3890 Zugriffe. Ich habe früher auf 128 KBit Leitungen DBFs mit Index geöffnet und mit dbseek in 20000 Datensätzen gesucht, das war rasend schnell (ich meine dbseek(), nicht das Öffnen, das daurte Sekunden).

Wenn deine Überlegung zutrifft, müsste die Suche nach dem logisch 10. Satz deutlich schneller sein als nach dem 10. letzten ?
Ich meine mich an Tests zu erinnern, in denen die dbseek Zeiten mit seconds() nicht messbar waren (auf lokalen Festplatten).

Jetzt geh ich doch mal in die Hilfedatei und schau mir die Beschreibung zu NTX an ... steht nix drin.
Wikipedia verweißt auf http://www.clicketyclick.dk/databases/x ... X_ALGORITH
und die bescheinigen selbst dem NDX ein b-Tree Verfahren. Hier die Zugriffsart in einer Indexdatei unter NDX.
Clippers NTX waren auf jeden Fall besser, warum genau weiß ich nicht mehr ;-) aber hier ist deren Aufbau beschrieben:
http://www.clicketyclick.dk/databases/x ... NTX_STRUCT
und ziemlich unten sieht man ein Feld 'Address of left page in tree' oben steht was von nächter Eintrag.

DER Vorteil von Clipper war damals doch, dass ich mich um den B-Tree Sch... nicht selbst kümmern muß. Ich geb zu, dass mir das im Unterricht zu hoch war ;-)

Also mach dir keine Sorgen um das Suchen in DBFs mit lächerlichen 3500 Datensätzen. Auch bei 300.000 macht NTX nicht schlapp.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Was Indexdateien deutlich langsamer macht ...

Beitrag von brandelh »

Hi Martin,

einen hab ich noch ...

Jede Form von Funktion im Index macht diesen langsamer, je komplexer eventuell auch noch selbst geschrieben umso mehr. Dennoch lebt meine Adressverwaltung mit Indexen auf eine Funktion, die die Umlaute in ae Form umsetzt.

Wenn du also schneller zugreifen willst, mach das Feld genauso wie du es brauchst, den Suchbegriff dann in der richtigen Form in eine local und dann ein einfaches dbseek() nach diesen Suchbegriff.
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
insgesamt werden in der DBF mal so um die 20.000 bis 30.000 Datensätze stehen - denke ich mal.
Und ja - die Suche nach dem 10 Eintrag ist schneller als die nach dem zehntletztem.
Wenn Du schon Messungen unternommen hast, dann bin ich ja beruhigt. Wenn also der Unterschied in der Geschwindigkeit zwischen einem gut austarierten und einem sequentiellen Baum nur in Bruchteilen von Sekunden liegen sollte, dann brauche ich mir da ja wirklich keinen Kopf zu machen... :D

Viele Grüße,
Martin
:grommit:
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.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Performance Test von dbseek() - Index on ...

Beitrag von brandelh »

Hi,

also das Thema hat mich nicht losgelassen und ich habe meine größte DBF bemüht um einige Suchfunktionen durchlaufen zu lassen.
Quellcode und Ergebnisse werde ich in mehreren Durchläufen senden, damit es noch einigermaßen übersichtlich bleibt.
Sollte mein Testprogramm echte Fehler enthalten, teilt es mir mit, ansonsten wird daran nichts mehr geändert.

Testrechner:

1. Athlon 64 3000+, 2 GB Ram, auf lokale Festplatte (Hitachi 160 GB 7200 rpm)
2. Pentium 3 Tulatin 1.26 GHz, 512 MB Ram, auf lokales (älteres) ATA Raid 5 Array (3x60 GB WD 5400 rpm).
3. Übers Netzwerk (1GBit) greift 2. auf die Daten von 1. zu...

Testdatei:

über 200000 Datensätze, über 350 MB groß (genaue Werte unten)
NTX Dateien 4 bis 6 MB groß.

Ergebnisse

Lokaler Indexaufbau auf ein Feld ohne Funktionen bei dieser Datei unter 5 Sekunden
Im Netzwerk unter 15 Sekunden, jeweils sonst unbelastete Systeme.

Indexzugriffe egal welcher Test immer 0.000 bis 0.010 Sekunden !

Natürlich wird es im gemischten Netzbetrieb mit mehreren Stationen und sich dauernd stark ändernden Datensätzen nicht so toll bleiben.
Daher lösche ich etwa monatlich meine Indexdateien und baue die neu auf.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Das Testprogramm

Beitrag von brandelh »

Code: Alles auswählen

proc main()
   local x, nStart, nEnde
   local aSuchRecNoAZ := {}, aSuchRecNoKEY := {}  // Suchbegriffe nach physikalischer Reihenfolge
   local aSuchIndexAZ := {}, aSuchIndexKEY := {}  // Suchbegriffe nach logischer Reihenfolge
   cls
   set alternate to TestNTX.TXT
   set alternate on

   delete file test_AZ.ntx
   delete file test_key.ntx
   ?
   ? "Testrechner Athlon 64 3000+, 2GB-Ram, 160 GB IBM 7200 Festplatte,"
   ? "                             Win2000 SP4 mit NTFS"
   ?
   ? str(seconds(),10,3),"TEST.DBF öffnen - exclusive für indizieren"
   use test.dbf exclusive
   if neterr()
      ? "**** NETERR() ****"
      quit
   endif
   ? str(seconds(),10,3),"20 Suchbegriffe: Recno() 1001, 2001 ... Lastrec()-1000 ..."
   go top
   for x := 1 to 10
       skip 1000
       aadd(aSuchRecNoAZ,field->AZ)
       aadd(aSuchRecNoKEY,field->KEY)
   next
   go bottom
   for x := 1 to 10
       skip -1000
       aadd(aSuchRecNoAZ,field->AZ)
       aadd(aSuchRecNoKEY,field->KEY)
   next
   ? str(seconds(),10,3),"LastRec():",ntrim(lastrec()),"RecSize()",ntrim(RecSize()),;
     "Byte -> Dateigröße:",transform( (RecSize()*LastRec()+Header()+1),"999,999,999"),"Byte"
   ? str(seconds(),10,3),"Datei indizieren auf Char-Feld 10 Stellen, mehrere Sätze mit gleichem Inhalt"
   index on key to test_Key
   ? str(seconds(),10,3),"FERTIG"
   ? str(seconds(),10,3),"Datei indizieren auf Char-Feld 20 Stellen, jeder Satz hat anderen Inhalt"
   index on AZ to test_AZ
   ? str(seconds(),10,3),"FERTIG"
   ? str(seconds(),10,3),"20 Suchbegriffe: nach logischer Reihenfolge je 1000 Schritte von Anfang bzw. Ende"
   // AZ
   set index to test_AZ
   go top
   for x := 1 to 10
       skip 1000
       aadd(aSuchIndexAZ,field->AZ)
   next
   go bottom
   for x := 1 to 10
       skip -1000
       aadd(aSuchIndexAZ,field->AZ)
   next
   // KEY
   set index to test_key
   go top
   for x := 1 to 10
       skip 1000
       aadd(aSuchIndexKEY,field->KEY)
   next
   go bottom
   for x := 1 to 10
       skip -1000
       aadd(aSuchIndexKEY,field->KEY)
   next
   ? str(seconds(),10,3),"Suchbegriffe sind gefunden, nun CLOSE ALL um Puffer zu leeren"
   close all
   ?
   ? str(seconds(),10,3),"TEST.DBF öffnen shared, das ist ja normal"
   use test.dbf shared
   if neterr()
      ? "**** NETERR() ****"
      quit
   endif
   ? str(seconds(),10,3),"Indexe öffnen ..."
   set index to test_AZ, test_key
   ? str(seconds(),10,3),"FERTIG"
   ?
   ? "Suche nach ... AZ - Suchbegriff aus RecNo()"
   set index to test_AZ
   go top
   for x := 1 to 10
       ? str(x,3)+". "
       nStart := seconds()       // direkt
       dbseek(aSuchRecNoAZ[x])
       nEnde  := seconds()       // messen
       if found()
          ?? "OK  - Dauer: "
       else
          ?? "OK  - Dauer: "
       endif
       ?? str(nEnde-nStart,6,3),"Sekunden"
   next
   ?
   ? "Suche nach ... KEY - Suchbegriff aus RecNo()"
   set index to test_KEY
   go top
   for x := 1 to 10
       ? str(x,3)+". "
       nStart := seconds()       // direkt
       dbseek(aSuchRecNoKEY[x])
       nEnde  := seconds()       // messen
       if found()
          ?? "OK  - Dauer: "
       else
          ?? "OK  - Dauer: "
       endif
       ?? str(nEnde-nStart,6,3),"Sekunden"
   next
   ?
   ? "Suche nach ... AZ - Suchbegriff aus logischer Reihenfolge"
   set index to test_AZ
   go top
   for x := 1 to 10
       ? str(x,3)+". "
       nStart := seconds()       // direkt
       dbseek(aSuchIndexAZ[x])
       nEnde  := seconds()       // messen
       if found()
          ?? "OK  - Dauer: "
       else
          ?? "OK  - Dauer: "
       endif
       ?? str(nEnde-nStart,6,3),"Sekunden"
   next
   ?
   ? "Suche nach ... KEY - Suchbegriff aus logischer Reihenfolge"
   set index to test_KEY
   go top
   for x := 1 to 10
       ? str(x,3)+". "
       nStart := seconds()       // direkt
       dbseek(aSuchIndexKEY[x])
       nEnde  := seconds()       // messen
       if found()
          ?? "OK  - Dauer: "
       else
          ?? "OK  - Dauer: "
       endif
       ?? str(nEnde-nStart,6,3),"Sekunden"
   next

return


function ntrim(nWert)
return alltrim(str(nWert))
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Die Ergebnisse der Tests ...

Beitrag von brandelh »

Beim allerersten Aufruf auf dem lokalen PC steht beim 1. Seek auch ein 0.010, danach scheint alles im Plattencache der Rechner erledigt zu werden.

Code: Alles auswählen

Testrechner Athlon 64 3000+, 2GB-Ram, 160 GB IBM 7200 Festplatte,
                             Win2000 SP4 mit NTFS

 43437.870 TEST.DBF öffnen - exclusive für indizieren
 43437.870 20 Suchbegriffe: Recno() 1001, 2001 ... Lastrec()-1000 ...
 43437.870 LastRec(): 223068 RecSize() 1643 Byte -> Dateigröße: 366.504.471 Byte
 43437.870 Datei indizieren auf Char-Feld 10 Stellen, mehrere Sätze mit gleichem Inhalt
 43440.230 FERTIG
 43440.230 Datei indizieren auf Char-Feld 20 Stellen, jeder Satz hat anderen Inhalt
 43442.600 FERTIG
 43442.600 20 Suchbegriffe: nach logischer Reihenfolge je 1000 Schritte von Anfang bzw. Ende
 43442.600 Suchbegriffe sind gefunden, nun CLOSE ALL um Puffer zu leeren

 43442.600 TEST.DBF öffnen shared, das ist ja normal
 43442.600 Indexe öffnen ...
 43442.600 FERTIG

Suche nach ... AZ - Suchbegriff aus RecNo()
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... KEY - Suchbegriff aus RecNo()
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... AZ - Suchbegriff aus logischer Reihenfolge
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... KEY - Suchbegriff aus logischer Reihenfolge
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Code: Alles auswählen



Testrechner Pentium 3 Tulatin 1233 Mhz, 512 MB-Ram, 
                      ATA Raid mit 3x 60 GB 5400 WD Festplatten
                             Win2000 SP4 mit NTFS

 44313.050 TEST.DBF öffnen - exclusive für indizieren
 44313.060 20 Suchbegriffe: Recno() 1001, 2001 ... Lastrec()-1000 ...
 44313.060 LastRec(): 223068 RecSize() 1643 Byte -> Dateigröße: 366.504.471 Byte
 44313.060 Datei indizieren auf Char-Feld 10 Stellen, mehrere Sätze mit gleichem Inhalt
 44317.450 FERTIG
 44317.450 Datei indizieren auf Char-Feld 20 Stellen, jeder Satz hat anderen Inhalt
 44322.160 FERTIG
 44322.160 20 Suchbegriffe: nach logischer Reihenfolge je 1000 Schritte von Anfang bzw. Ende
 44322.160 Suchbegriffe sind gefunden, nun CLOSE ALL um Puffer zu leeren

 44322.160 TEST.DBF öffnen shared, das ist ja normal
 44322.170 Indexe öffnen ...
 44322.170 FERTIG

Suche nach ... AZ - Suchbegriff aus RecNo()
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... KEY - Suchbegriff aus RecNo()
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... AZ - Suchbegriff aus logischer Reihenfolge
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... KEY - Suchbegriff aus logischer Reihenfolge
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Code: Alles auswählen



Testrechner Pentium 3 Tulatin 1233 Mhz, 512 MB-Ram, 
                             über 1 GB-Netz auf 160 GB IBM 7200 Festplatte von Athlon
                             Win2000 SP4 mit NTFS

 44121.250 TEST.DBF öffnen - exclusive für indizieren
 44121.420 20 Suchbegriffe: Recno() 1001, 2001 ... Lastrec()-1000 ...
 44121.430 LastRec(): 223068 RecSize() 1643 Byte -> Dateigröße: 366.504.471 Byte
 44121.440 Datei indizieren auf Char-Feld 10 Stellen, mehrere Sätze mit gleichem Inhalt
 44133.540 FERTIG
 44133.540 Datei indizieren auf Char-Feld 20 Stellen, jeder Satz hat anderen Inhalt
 44138.240 FERTIG
 44138.240 20 Suchbegriffe: nach logischer Reihenfolge je 1000 Schritte von Anfang bzw. Ende
 44138.360 Suchbegriffe sind gefunden, nun CLOSE ALL um Puffer zu leeren

 44138.360 TEST.DBF öffnen shared, das ist ja normal
 44138.400 Indexe öffnen ...
 44138.410 FERTIG

Suche nach ... AZ - Suchbegriff aus RecNo()
  1. OK  - Dauer:  0.010 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... KEY - Suchbegriff aus RecNo()
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.010 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... AZ - Suchbegriff aus logischer Reihenfolge
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.000 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden

Suche nach ... KEY - Suchbegriff aus logischer Reihenfolge
  1. OK  - Dauer:  0.000 Sekunden
  2. OK  - Dauer:  0.000 Sekunden
  3. OK  - Dauer:  0.000 Sekunden
  4. OK  - Dauer:  0.000 Sekunden
  5. OK  - Dauer:  0.010 Sekunden
  6. OK  - Dauer:  0.000 Sekunden
  7. OK  - Dauer:  0.000 Sekunden
  8. OK  - Dauer:  0.000 Sekunden
  9. OK  - Dauer:  0.000 Sekunden
 10. OK  - Dauer:  0.000 Sekunden
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
prima - vielen Dank!!
Willst Du Deine Motivation und Energie nicht in das Programmieren einer kleinen DevCon-App stecken :?: Bild

Viele Grüße,
Martin
:grommit:
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.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Habt Ihr noch keine ?

Wir reden mal drüber ... :glasses5: :glasses6: privat :D
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
nee - noch nicht! Bin gerade erst damit fertig geworden, die Anmeldeseiten auf Spanisch anzupassen (also Claudias Übersetzungen einzuarbeiten) und die DevCon-Seiten auf Englisch zu übersetzen.
Jetzt drängeln auch noch die eigenen Kunden, die unbedingt den (anderen) Webserver erweitert haben wollen (darum die anderen Threads mit der Eineindeutigkeit eines Schlüssels und dieser Thread hier)...
Und nebenbei muss ich ja auch noch hier im Büro (Bank) arbeiten und mein Geld verdienen...
Naja - das Übliche halt :lol:

Viele Grüße,
Martin
:grommit:
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.
Krause
UDF-Programmierer
UDF-Programmierer
Beiträge: 52
Registriert: Mo, 08. Jan 2007 8:55
Wohnort: In Thüringen

Beitrag von Krause »

Hallo Martin,

wir haben hier, ähnlich wie Hubert beschrieben hat, keine Probleme mit NTX – Dateien im lokalen Netzwerk. Unsere größte Archivdatei enthält 233.000 Datensätze (112 MB DBF- / 14 MB NTX – Dateigröße). Nehmen wir mal an, dass wie in deinem Beispiel, der Primary Key einen Bezug zum Jahr hat, dann könnte man mit zwei Index - Dateien

Code: Alles auswählen

1- ter:       INDEX ON  CNTVALUE  FOR CNTYEAR="07"
2- ter:       INDEX ON  CNTVALUE  FOR ! (CNTYEAR="07")
ein sehr schnelles System mit geringer Netzwerklast zusammenbasteln. Das laufende Geschäftsjahr ist in einem relativ kleinem Index abgebildet. Dreht man nun den Counterwert, dass heißt aus 0001 wird zum Bsp. 1000, aus 0012 wird 2100 (vorausgesetzt, der Vergleich beginnt mit dem ersten Zeichen von links) , bekommt man noch einen zusätzlichen, wenn auch bei der heutigen Ausstattung der Rechentechnik minimalen Kick ...


Mit freundlichen Grüßen
Joachim Krause
Antworten