Announcement

Collapse
No announcement yet.

Träge Firebird-Datenbank ...

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Träge Firebird-Datenbank ...

    Moin allerseits!

    Gegeben ist eine Firebird-Datenbank (Heilpflanzen) mit 11 Tabellen. Die Haupttabelle enthält mehrere Blob-Felder (formatierter RTF-Text), eine Tabelle enthält zahlreiche mittelgroße Bilder (2000*2000 Pixel). Die Anzeige der Bilder ist zwar etwas träge, aber noch erträglich. Die Bilder müssen so groß sein, damit sie in anständiger Qualität gedruckt werden können. Die Datenbank selbst ist derzeit 60 BM groß

    Eine weitere Tabelle enthält bislang ca. 350 Einträge (Fertigpräparate) mit zugehörigem RTF-Text (Jedi-DBRichText mit je einem Bild und einer Din-A-4-Seite Text in binärem Blob-Feld). In einer Zwischentabelle werden die Beziehungen zwischen Haupttabelle und Präparatetabelle gespeichert (2 Spalten). Die Clientsoftware erstelle ich mit Delphi 2009 pro.

    Auf dem Hauptformular ist eine Tabelle in die Eingabemaske eingebettet, die immer nur die entsprechenden, zur Pflanze gehörenden Einträge anzeigt - realisiert mit gesetztem Filter in der Beziehungs-Tabelle, der sich natürlich bei jedem Browsing ändert.

    Um nun dem Anwender beim Editieren bzw. Einfügen von Datensätzen in die Haupttabelle (Pflanzen-Namen usw.) zu ermöglichen, den einzelnen Pflanzen entsprechende Fertigpräparate zuordnen zu können, wird im Edit- bzw. Append-Modus die Tabelle ausgeblendet (Visible := false) und eine Checklistbox eingeblendet. Und genau hier liegt der Knoten: das geht unerträglich langsam. Mir fällt aber keine bessere Lösung ein, wie der Anwender aus der vorhandenen Liste an Fertigpräparaten diejenigen auswählen könnte, die die Droge der angezeigten Pflanze enthalten.

    Code:
    {******************************************************************************************************************
     *** CHECKLISTBOX FÜR FERTIGARZNEIEN MIT PRÄPARATEN FÜLLEN                                                      ***
     ******************************************************************************************************************}
    PROCEDURE FILL_Praeparate;
    VAR
       Aus         : STRING;
       i,zp, x, px : LONGINT;
       idx         : INTEGER;
    
    BEGIN
         FormMain.DBGrid_Arznei.Visible       := FALSE;
         FormMain.CheckListBox_Arznei.Left    := FormMain.DBGrid_Arznei.Left;
         FormMain.CheckListBox_Arznei.Top     := FormMain.DBGrid_Arznei.Top;
         FormMain.CheckListBox_Arznei.Width   := FormMain.DBGrid_Arznei.Width;
         FormMain.CheckListBox_Arznei.Height  := FormMain.DBGrid_Arznei.Height;
         FormMain.CheckListBox_Arznei.Sorted  := FALSE;
         FormMain.CheckListBox_Arznei.Visible := TRUE;
    
         DatMod.Dset_Praeparat.Last;
         zp := DatMod.Dset_Praeparat.RecordCount;
         x  := DatMod.Dset_Pflanzen.FieldByName('IDX_PFLANZ').AsInteger;
    
         FOR i := 1 TO zp DO
         BEGIN
              DatMod.Dset_Praeparat.RecNo := i;
              px := DatMod.Dset_Praeparat.FieldByName('IDX_PRAEPARAT').AsInteger;
              Aus := DatMod.Dset_Praeparat.FieldByName('ARZNEI').AsString;
              FormMain.CheckListBox_Arznei.Items.Append(Aus);
              idx := FormMain.CheckListBox_Arznei.Count -1;
              IF NOT EditModusArznei THEN
              BEGIN
                   IF   DatMod.Dset_PflanzPraep.Locate('PFLANZE;PRAEPARAT', VarArrayOf([x,px]),[])
                   THEN FormMain.CheckListBox_Arznei.Checked[idx] := TRUE
                   ELSE FormMain.CheckListBox_Arznei.Checked[idx] := FALSE;
              END;
         END;
    
         FormMain.CheckListBox_Arznei.Sorted  := TRUE;
         FormMain.CheckListBox_Arznei.Visible := TRUE;
    END;
    Wenn der Anwender mit der Bearbeitung fertig ist und postet, wird die CheckListBox abgeklappert und die entsprechenden Verbindungen hergestellt bzw. gelöscht:

    Code:
    PROCEDURE CLEAR_Praeparate;
    VAR
       Aus   : STRING;
       idx,
       i,z,x : LONGINT;
       Fund  : BOOLEAN;
    
    BEGIN
         x  := DatMod.Dset_Pflanzen.FieldByName('IDX_PFLANZ').AsInteger;
         z  := FormMain.CheckListBox_Arznei.Count -1;
    
         FOR i := 0 TO z DO
         BEGIN
              Aus := FormMain.CheckListBox_Arznei.Items[i];
              DatMod.Dset_Praeparat.Locate('ARZNEI',Aus,[]);
              idx := DatMod.Dset_Praeparat.FieldByName('IDX_PRAEPARAT').AsInteger;
          IF FormMain.CheckListBox_Arznei.Checked[i] THEN
          BEGIN
               IF NOT DatMod.Dset_PflanzPraep.Locate('PFLANZE;PRAEPARAT', VarArrayOf([x,idx]),[]) THEN
               BEGIN
                    DatMod.Dset_PflanzPraep.Append;
                    DatMod.Dset_PflanzPraep.FieldByName('PFLANZE').AsInteger   := x;
                    DatMod.Dset_PflanzPraep.FieldByName('PRAEPARAT').AsInteger := idx;
                    DatMod.Dset_PflanzPraep.Post;
               END;
    
          END ELSE
          BEGIN
               IF   DatMod.Dset_PflanzPraep.Locate('PFLANZE;PRAEPARAT', VarArrayOf([x,idx]),[])
               THEN DatMod.Dset_PflanzPraep.Delete;
          END;
         END;
    
         FormMain.CheckListBox_Arznei.Clear;
         FormMain.CheckListBox_Arznei.Visible := FALSE;
         FormMain.DBGrid_Arznei.Visible       := TRUE;
         DatMod.Trans_PflanzPraep.Commit;
         Application.ProcessMessages;
         DatMod.Dset_PflanzPraep.Active := TRUE;
         DatMod.Dset_PflanzPraep.DoSort(['V_Praeparat'],[TRUE]);
         DatMod.Dset_PflanzPraep.Refresh;
    END;
    Beide Abläufe dauern sehr lange, das Auslesen der Checklistbox ca. 11 Sekunden, das Einlesen der Tabelle PRAEPARATE dauert nur etwa 5 Sekunden bei derzeit ca. 350 Einträgen. Wenn ich mir nun ausmale, wie das erst sein wird, wenn alle Einträge drin sind - das werden dann schätzungsweise 3000 bis 4000 sein - wird mir schon jetzt ein wenig übel ...

    Hat vielleicht jemand ein besseres Konzept, wie ich dieses Nadelöhr umgehen könnte?

    Übrigens: wie schalte ich hier Delphi-Code?

    Browse-Modus:



    Edit-Modus:



    Tabelle Fertigpräparate:

    Zuletzt editiert von Perlsau; 04.09.2010, 07:43. Reason: Bitmap eingefügt
    Die Tränen, die du nicht weinen willst, müssen andere für dich vergießen. (Frei nach: wer nicht leiden will, muß hassen.)

  • #2
    Hallo,

    stell mal deine DataSource auf Enabled := false; während Du durch die Datenmengen navigierst.

    mfg
    M. Pannier

    Comment


    • #3
      Originally posted by M.Pannier View Post
      Hallo, stell mal deine DataSource auf Enabled := false; während Du durch die Datenmengen navigierst.
      Danke, das hat geholfen!
      Die Tränen, die du nicht weinen willst, müssen andere für dich vergießen. (Frei nach: wer nicht leiden will, muß hassen.)

      Comment

      Working...
      X