Performance beim suchen und schreiben

19. Februar 2007 12:33

Ich habe folgendes Problem:

Ich habe für einen Kunden eine Artikel-Klassifizierung programmiert.

Ein Artikel kann einer Kategorie und einer Klasse zugeordnet werden und dann können Merkmale definiert werden nach welchen dieser Artikel klassifiziert werden darf/kann.

Um das zuweisen neuer Kriterien individuell zu ermöglichen speichere ich die Daten nach folgendem Aufbau:

Artikel Kategorie Klasse Kriterium WertText WertDecimal

Um jetzt aber dem User eine Suchmaske aufzubauen habe ich ein Form erstellt, welches nach der Auswahl von der Kategorie und Klasse ein Form aufbaut mit den Spalten: Artikel, Krtiterium 1, Kriterium 2, usw.

Um dies zu ermöglichen muss ich beim Aufbau der Tabelle alle Werte nacheinander raus suchen und dann in der richtigen Spalte speichern.

Ist in der Theorie recht einfach das ganze funktioniert auch recht gut, jedoch wenn mal nach 30.000 Datensätzen gesucht wird dauert die Sache fast zwei Minuten.

Der eigentliche Code sieht so aus:


Code:
  ClassLedgerEntry.SETCURRENTKEY("Item No.",Category,Class);
  ClassLedgerEntry.SETRANGE(Category, ItemCategoryCode);
  ClassLedgerEntry.SETRANGE(Class,ProductGroupCode);
  IF ClassLedgerEntry.FINDFIRST THEN BEGIN
    REPEAT
      IF NOT ClassSearch.GET(ClassLedgerEntry."Item No.",ClassLedgerEntry.Category,
      ClassLedgerEntry.Class) THEN BEGIN
        ClassSearch.INIT;
        ClassSearch."Item No." := ClassLedgerEntry."Item No.";
        ClassSearch.Category := ClassLedgerEntry.Category;
        ClassSearch.Class := ClassLedgerEntry.Class;
      END;
      IF ClassLedgerEntry."Value Text" <> '' THEN BEGIN
        FindCollumText;
      END ELSE BEGIN
        FindCollumDecimal;
      END;
      IF NOT ClassSearch.INSERT THEN
        ClassSearch.MODIFY;
    UNTIL ClassLedgerEntry.NEXT = 0;


In den Funktionen FinCollumText und FindCollumDecimal such ich die richtige Spalte.

Auch über den Client-Monitor komme ich nicht drauf was ich hier falsch mache.

Villeicht kann mir hier jemand weiterhelfen.

Danke im Voraus

[hr][Edit: Programmcode der Lesbarkeit halber in [code]-Blöcke gepackt. Gruß, Timo Lässer]

19. Februar 2007 13:04

Zwei Dinge fallen mir an deinem Programmcode auf:
  1. Du verwendest zur Sortierung den Schlüssel "Item No.",Category,Class, gefiltert wird aber nur auf die letzten beiden Felder des Schlüssels.
    Der Schlüssel ist somit nicht optimal.
  2. FINDFIRST bzw. FINDLAST darf nur dann verwendet werden, wenn du nur den ersten oder letzten Datensatz benötigst.
    Du durchläufst damit aber eine Schleife.
    Besser wäre hier FINDSET, wobei dieser Befehl auch nur bis 500 Datensätze seine Vorteile ausspielen kann.
    Nutze hier einfach wieder den alten Befehl FIND('-')

19. Februar 2007 17:33

Hallo Timo!

Vielen Dank für deine Tips. Leider habe ich da schon mehrmals herumgefeilt, da ist es mit dem Key und Findset aber schon dabeigewesen.

Jedoch habe ich den Code jetzt so modifiziert und bekomme im nach ca. 3 Minuten im Client-Monitor häufig solche Blöcke zu sehen:

Code:
Datum   Uhrzeit   Lfd. Nr.   Funktionsname   Parameter-Nr.   Parameter   Anzahl   Daten
19.02.07   15:24:41,329   591080   FIND/NEXT   1   Table   50041   Classification Ledger Entry
19.02.07   15:24:41,329   591080   FIND/NEXT   2   Search Method      >
19.02.07   15:24:41,329   591080   FIND/NEXT   3   Key      Kategorie='TW17',Klasse='GERÄTE',Item No.='C1-13094',Merkmal Code='BAUGRÖßE'
19.02.07   15:24:41,329   591080   FIND/NEXT   6   Filter      Kategorie:TW17, Klasse:GERÄTE
19.02.07   15:24:41,329   591080   FIND/NEXT   14   Source Object      Form 50029 Klassifikation Suche
19.02.07   15:24:41,329   591080   FIND/NEXT   15   Source Trigger/Function      GetValues()
19.02.07   15:24:41,87   591080   FIND/NEXT   16   Source Line No.   41   
19.02.07   15:24:41,87   591080   FIND/NEXT   17   Source Text      UNTIL ClassLedgerEntry.NEXT = 0;
19.02.07   15:24:41,87   591080   FIND/NEXT   50   Search Result      >
19.02.07   15:24:41,87   591080   FIND/NEXT   51   Record Found      Item No.='C1-13094',Kategorie='TW17',Klasse='GERÄTE',Merkmal Code='BETÄTIGUNG'
19.02.07   15:24:41,87   591080   FIND/NEXT   55   Records Read   2   
19.02.07   15:24:41,87   591080   FIND/NEXT   100   Elapsed Time (ms)   541



Wobei natürlich auf dieser Code-Zeile UNTIL ClassLedgerEntry.NEXT = 0; eigentlich nichts passiert ...

Trotzdem benötigt er 541 Millisekunden ???

Ich bin hier langsam Ratlos.

Schöne Grüße

Christian F.

[hr][Edit: Auszug des Client Monitors der Lesbarkeit halber in [code]-Blöcke gepackt. Gruß, Timo Lässer]