Announcement

Collapse
No announcement yet.

BDE ohne virtuellen Speicher?!

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

  • BDE ohne virtuellen Speicher?!

    Ich habe eine Produkt Datenbank, die mehrere hunderttausend Einträge enthält, jetzt gibt es eine Situation, in der so ein bis zwei hunderttausend in ein dbgrid müssen, durch den richtigen index geht das öffnen über ein ttable noch recht flott, allerdings, wenn man ein Stück zu weit scrollt, kann man sich schlafen legen, weil dann die bde anfängt alles in den virtuellen speicher zu schaufeln, dann geht nichts mehr. Gibt es eine Möglichkeit, der BDE beizubringen, den Anfang einfach wieder zu vergessen und bei bedarf neu aus der tabelle zu holen ohne virtuellen speicher anzuknabbern? Ich denke, das wäre schneller.

  • #2
    Hallo,

    um welche Datenbank handelt es sich? Normalerweise ist es keine gute Idee, hunderttausend Datensätze <b>gleichzeitig</b> im DBGrid abzulegen. Ich glaube nicht, das irgendwer in der Lage ist, mit derart vielen Datensätzen zu navigieren, ohne die Übersicht zu verlieren. Ich würde über eine WHERE-Einschränkung (bei TTable wird ein Filter bei einer SQL-Datenbank automatisch in die korrekte WHERE-Einschränkung übersetz) die Anzahl der Datensätze in der aktiven Datenmenge einschränken

    Comment


    • #3
      Also das Problem ist folgendes, ich schreibe zur Zeit Angebotsprogramm für das Handwerk, im Handwerk werden alle notwendigen Artikeldaten über die Standardschnittstelle Datanorm übertragen. Pro Großhändler kommen da schnell ein paar hundert tausend Sätze zusammen, das Problem ist, das es eben auch möglich sein soll, z.B. die Badewannen aller Anbieter gleichzeitig anzuzeiegn, daher wäre es eine schlechte idee, pro Anbieter eine Tabelle zu erzeugen, denn in diesem Fall müßte man ja dann einen dynamischen join über x tabellen erzeugen, den müßte man dann warscheinlich 2 tage bevor man ihn braucht starten und wie ich mein glück kenne, würde warscheinlich spätestens wenn 8 Tabellen da sind eine Exception wegen zu langem sql statement hochkommen Problem zwei ist aber, das der Anwender trotz Programm häufig mit Katalog arbeitet und dann per Artikelnummerneingabe im Datenbestand eines Anbieters hin und her springen will

      Comment


      • #4
        Hallo Karsten,

        ich kann mir nicht so richtig vorstellen, das dieser Effekt am virtuellen Speicher der BDE oder am DBGrid liegt.
        Ich verwende beides mit Paradox-Tabellen die über 150.000 Datensätze enthalten. Aber prüfe mal folgendes:

        1. Was für eine Tabellentyp benutzt Du denn, Paradox, dBase, ODBC ?

        2. Benutzt Du bei der TTable einen Filter ? Wenn Ja, dann teste es doch mal mit TQuery und einer WHERE-Anweisung, denn
        Filter und TTable = gähn ;-)

        3. Besitzt Deine Tabelle Memo- oder Blob-Felder die mit vielen Daten gefüllt sind ? Dann lagere sie in eine andere Tabelle aus und
        bilde eine Referenz über den Primärindex der Haupttabelle. Dadurch geht das Bewegen in der Hauptdatenmege schneller.

        4. Versuche mal für alle abzufragenden Felder einen Index zu erstellen

        Comment


        • #5
          Naja, daß Problem ist ja, das die Tabelle mehrere hundert Tausend Einträge hat und ich einen Teil daraus anzeigen will. Mit TQuery hab ich es zuerst versucht, da taucht das Prblem auf, das das öffnen gähn ist (virtueller speicher wird benutzt). Die Tabellenstrucktur ist leider sehr mächtig (47 Spalten, einige davon memos und ein paar längere Char Spalten), es sind aber zusätzlich schon fünf weitere Tabellen verknüpft, was dem Scrollen nicht gut tut, obwohl ich schon je nachdem welches Tab offen ist einzelne verknüpfte tabellen ab und zu schalte. Da alles lokal gehalten wird und das auch so bleiben soll bin ich jetzt mal auf ttable umgestiegen, damit wenigstens das öffnen schnell geht, da das scrollen ja eben durch den virt. speicher auch mit query nicht gut war. Zusätzlich fällt mir jetzt noch auf, das Paradox seinem eigenen index scheinbar nicht traut: Eins meiner Performance Probleme ist, daß ich auf einen zusammengesetzten primärindex angewiesen bin, das ergibt sich daraus, daß eben die Artikelnummern der verschiedenen hersteller nicht eindeutig sind, jeder vergibt seine eigenen wie er will, also muss eine herstellernummer dazu, das klappt aber eigentlich gut, ein SELECT * FROM artikel WHERE firmno = 1 AND LOWER(kurz1) LIKE "%badewanne%" klingt bei der Datenmenge brutal geht aber sehr flott (3-5 sekunden), wenn der hersteller unter 100.000 artikel hat, teste ich mit firmno = 0 die es nicht gibt, durchsucht er offensichtlich die gesamte Tabelle (10-15 minuten), den index nurfirmno gibts natürlich. Achso, das auslagern von bestimmten teilen wird natürlich durch den doppelten index noch erschwert, und nur dafür noch einen eindeutigen einführen und die tabelle nochmal aufpumpen (und noch ein index)

          Comment


          • #6
            Hmm, scheint keinem etwas zu einzufallen, jetzt ist mir aber etwas merkwürdiges aufgefallen, womit das ganze zu tun haben dürfte, nach jedem absetzen eines neuen Sql-Statements (immer mit der gleichen TQuery) verschwindet mehr Speicher, auch wenn die neue Ergebnismenge viel kleiner ist als die vorherige, so als würde die letzte Ergebnismenge nicht aus dem Speicher entfernt. Es werden keine weiteren Aktionen ausgeführt (auch kein after open oder so) nur öffnen, daher Anzeige im Grid, dann schließen und mit neuem sql öffnen

            Comment


            • #7
              Hallo,

              um auf die allererste Frage zurückzukommen: Ja, es gibt eine Möglichkeit, der BDE zu sagen, dass keine Daten lokal zwischengepuffert werden sollen. In der Delphi-Hilfe ist als Beschreibung für <b>UniDirectional</b> der folgende Satz zu finden: "<i>Ursprünglich kann ein SQL-Cursor in einer Datenmenge nur vorwärts bewegt werden. Durch die Zwischenspeicherung von Datensätzen ist in der BDE auch die Verschiebung in der anderen Richtung möglich. Muß der Cursor in einer Ergebnismenge nicht in beide Richtungen bewegt werden, setzen Sie UniDirectional auf True. In diesem Fall ist für eine Anwendung weniger Speicher erforderlich, und die Leistung wird verbessert.</i>.

              Allerdings bedeutet UniDirectional auch, dass kein (!) DBGrid verwendet werden darf, womit sich der Kreis wieder schliesst ;-

              Comment


              • #8
                Na Klasse, bringt mich also exakt keinen Schritt weiter :´o~( <p> Und was ist mit der letzten Frage?

                Comment


                • #9
                  Hallo,

                  mit welchen Mitteln wurde "verschwindet mehr Speicher" entdeckt bzw. bestimmt

                  Comment


                  • #10
                    Einfach nur mit Regelmäßiger Windowsabfrage (über Timer) des freien REALEN speichers, also ohne den virtuellen Speicher zu berücksichtigen, aber grede der Reale Speicher sollte ja nach Active := False wieder freigegeben werden?!

                    Comment


                    • #11
                      Kann ich bestätigen .Der Speicher wird nach einer SQL-Anfrage teilweise nicht freigegeben. Es scheint ein BDE-Problem zu sein und hat nichts mit VCL's wie etwa Grid zu tun. Folgender Code zur SQL-Abfrage führt von Anfrage zu Anfrage zur zunehmenden Speicherauslastung.

                      function fDbiQExec(hTmpDb: hDBIDB; TblName, SQL: string): Longint;<br>
                      var<br>
                      hStmt: hDBIStmt;<br>
                      hQryCur, hNewCur: hDBICur;<br>
                      iRecCount: LongInt;<br>
                      begin<br>
                      hQryCur := nil;<br>
                      hNewCur := nil;<br>
                      hStmt := nil;<br>
                      try<br>
                      Check(DbiQAlloc(hTmpDb, qrylangSQL, hStmt));<br>
                      Check(DbiQPrepare(hStmt, PChar(SQL)));<br>
                      Check(DbiQExec(hStmt, @hQryCur));<br>
                      Check(DbiQInstantiateAnswer(hStmt, hQryCur, PChar(TblName), szDBASE,True, @hNewCur));<br>
                      Check(DbiGetRecordCount(hNewCur, iRecCount));<br>
                      Result := iRecCount;<br>
                      finally<br>
                      if (hStmt <> nil) then<br>
                      Check(DbiQFree(hStmt));<br>
                      if (hNewCur <> nil) then<br>
                      Check(DbiCloseCursor(hNewCur));<br>
                      end;<br>
                      end;<br&gt

                      Comment


                      • #12
                        Und, kann man da nichts dran machen?

                        Comment


                        • #13
                          Hallo Karsten,

                          Zum verschwinden von Speicher:
                          Verwendest Du das neueste BDE-Update 5.1.1.1 (download file bde511ge.exe) ?

                          Zum langsamen SQL:
                          Vielleicht TQuery.RequestLive := FALSE setzen. Ein editieren der Daten ist dann aber nicht möglich

                          Comment


                          • #14
                            Leider beides schon passiert )o

                            Comment

                            Working...
                            X