Announcement

Collapse
No announcement yet.

Geschwindigkeit bei Datenbanken

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

  • Geschwindigkeit bei Datenbanken

    Meine DB Einsatzfälle sind im Vergleich zu den anderen hier sehr einfach, fast hobbyhaft
    Ich muß auf "einmal" 100000-200000 Datensätze in eine Datenbank schreiben, danach wird sie nicht mehr verändert. Dort muß ich etwas suchen und sortieren können.

    Bis zur BDE4.x dauerte sowas 10-20 Minuten.<BR>
    Mit der BDE5.x dauerte dieser Vorgang dann 2-3 Stunden. Damit war die Lösung unbrauchbar.<BR>
    Der selbe Vorgang dauerte in Visual FoxPro 2-3 Minuten !!!<BR>

    Nun suche ich nach neuen Lösungen wie ADO mit Accress, Interbase.<BR>

    Aber ganz gleich was ich in den letzen Tagen ausprobiert habe, ich werde das Gefühl nicht los, daß ich entweder etwas falsch mache oder das man wirklich schnelle DB Anwendungen auf dem PC unter Windows nur in Visual Foxpro schreiben kann.

    Kann mir jemand etwas wirklich schnelles empfehlen, ich brauche keine Netzwerklösung, aber schnell muß sie sein. Kein Mensch kann mehrere Stunden auf einen Vorgang warten, wenn FoxPro das in ein paar Minuten kann.

  • #2
    Hallo Peter,<BR>

    bei der BDE ist ggf. ein wichtiger Faktor, ob die Indizes beim füllen schon existieren oder erst danach erstellt werden! Mein letzter Stand mit der BDE war deshalb, daß ich die Zieltabelle ( ohne Sekundär-Indizes ) erstellt, die Daten importiert und anschl. die Sekundär-Indizes erstellt habe. Die Zeitersparnis war wirklich dramatisch!<BR>

    Für meine kleineren Kundenprojekte setze ich inzwischen die Jet 4.0 ( .mdb ) ein; für gut 300.000 Datensätze benötige ich für den Import derzeit ca. 3-5 Minuten ( simple SQL-Anweisung ).<BR>

    Mfg Holger Rogg

    Comment


    • #3
      hi

      wo kommen die Datensätze her?
      wie groß(lang)sind die datensätze?
      sind alle datasources disabled, so dass wirklich nur der import stattfindet und nicht irgendwo doch andere, zu diesem zeitpunkt unnötige, routinen mitarbeiten?

      ich fürchte, ein paar informationen dürften es schon mehr sein, um dem problem auf den leib rücken zu können

      gruß,bernhar

      Comment


      • #4
        Hallo,
        ich habe es auch so gemacht, daß ich erst die Tabelle gefüllt habe und dann die Indizes erzeuge. Das muß ich schon deshalb machen, weil es offensichtlich bei der BDE einen Fehler gibt, der dafür sorgt, daß das Programm bei ca. 15000 Datensätzen (die exakte Zahl ist konstant) sich aufhängt. Das war mit der BDE 4.X ebenfalls so und hat sich auch mit der BDE 5.x nicht geändert

        Danach habe ich drei simple Indizes erzeugt. Das dauerte durch den Wechsel auf BDE5 plötzlich mehrere Stunden. Wir haben lange gebraucht um das zu erkennen, bei einer so langen Zeit rufen Kunden natürlich an und berichten, der Rechner würde sich aufhängen.

        Borland hat mir daraufhin gesagt, daß es eben so ist wie es ist. In anderen Artikeln hier im Forum habe ich von ähnlichen Erfahrungen gelesen.

        Ich erzeuge nun die Indizes durch den Anruf eines kleinen FoxPro-Programmes. Solange ich darauf vertrauen kann, daß ich DBASE- genauer FoxPro-Dateien auch Morgen noch mit de BDE erzeugen kann, kann ich damit leben. Die Lösung ist zwar ziemlich exotisch, funktioniert aber sehr gut.

        Nur, es ist wirklich so, daß der Vorgang des Indizieren mit BDE bei einer so großen Datei mehrere Stunden dauert und FoxPro den Vorgang in 2-3 Minuten erledigt. Mit ADO und ;DB scheint es nun auch wieder eine langsame Lösung zu geben.

        Die FoxPro Indexdatei hat dann auch nur 10% der Größe einer BDE MDX Datei. Ich mache genauso viel mit Foxpro wie mit Delphi, daß die Fox Datenbank wirklich um Klassen schneller ist als andere habe ich schon vor Jahren festgestellt, aber um so einen Faktor ?

        Die Daten müssen in einem Rutsch eingelesen werden, weil Sie in einem externen Gerät im Laufe von Wochen entstehen. Das ist vergleichbar mit einer Black-Box beim Flugzeug. Das Programm muß die Daten auf dem PC auswerten.

        Es gibt 14 Felder mit einer Gesamtbreite von 214 Byte und 3 Indizes. Ich habe die Datensatzbreite versuchsweise reduziert, ohne Verbesserung
        Es gibt auch keine Oberflächenelemente die aktualisert werden müssen.

        Ich habe nun ADO mit MDB Dateien versuchsweise genommen, das scheint aber genauso langsam zu sein.

        Wenn 300.000 Datensätze in 3-5 Minuten eingelesen werden, wäre das genial. Kannst Du die Lösung näher beschreiben ? Wahrscheinlich nimmst Du den Insert-Befehl, ich werde es einmal damit versuchen.

        Ich nehme ein "ADOTable", weise die Daten mit "FieldByname" in einer einfachen For-Schleife zu und rufen den Befehl "post" auf. Das wars schon. Ich arbeite mit Delphi 6.

        mfg
        Peter Schröde

        Comment


        • #5
          Hallo Peter,<BR><BR>eine wichtige Frage ist natürlich wie die Daten ursprünglich vorliegen. Wenn das eine Textdatei ist, dann ist Access eigentlich sehr gut geeignet. Es gibt da folgende Möglichkeit:<BR><BR>SELECT * INTO TAB_NAME IN "x:\DieDatenbank.mdb" from Datei#txt<BR><BR>Diesen Befehl kannst du direkt mit ADOConnection.Execute abschicken und das geht wirklich schnell! Benutze also auf keinen Fall eine Schleife, das ist langsam. Auf eine Sache solltest du ebenfalls achten, ADOConnection.CursorLocation sollte bei Access-Datenbanken grundsätzlich auf clUseServer stehen. Das bringt bringt auch nochmal "Punkte".<BR>Vielleicht wirst du ja auch noch etwas konkreter, dann fällt mir vielleicht auch noch etwas mehr ein :-).<BR><BR>Viele Grüße Ola

          Comment


          • #6
            Hallo,
            ich werde das in den nächsten Tagen einmal überprüfen, unglücklicherweise habe ich nun ein paar Tage Urlaub.

            Die Daten stehen in einer verschlüsselten Datei, Sie müssen also zunächst Zeile für Zeile errechnet werden und dann Satz für Satz in die Datei geschrieben werden

            Hier ist der Teil um den es geht

            ADOTable1.Open;<BR>
            for iii := 1 to 1000 do<BR>
            begin<BR>
            ADOTable1.AppendRecord (['Daten', 'Nummer 0815', 4711, 100, StrToDate('10.10.2003')]);<BR>
            end;<BR>

            Auf meinem sicher 450MHz Rechner mit Windows XP brauche ich 29 Sekunden. Bei 100000 Datensätzen brauche ich dann ca. 50 Minuten, das ist zwar deutlich schneller als mit der BDE, aber Visual FoxPro braucht statt 29 Sekunden auf dem selben Rechner deutlich weniger als 1 Sekunde.

            Der ganze Vorgang wird dann weniger als 2 Minuten dauern, da wird mir niemand die andere Lösung abnehmen.

            Trotzdem erst einmal Danke

            Pete

            Comment


            • #7
              Hallo Leute,

              kann es sein, daß das ein Delphi-Problem ist?

              Ich hab' das hier mal mit meinem BCB6 probiert.
              Ergebnis 200.000 Datensätze in eine Paradox Datei schreiben: 24 Sek. mit Primärindex auf char, 10 Sek. mit Primärindex int auf AUTOINC.
              In der Tabelle befinden sich 13 weitere Felder vom Typ char. Pro weiteren Index benötige ich hier 7 Sek. (Index auf Feld1, Feld 1 + 2, Feld 3 + 4). Als Werte habe ich jeweils eine Zufallszahl zwischen 1 und 50.000 plus die Datenssatznummer als char in die Tabelle geschrieben.

              Hier ist die Testroutine:
              <PRE>
              q->SQL->Text = "DROP TABLE \"test.db\"";
              q->ExecSQL();
              q->SQL->LoadFromFile("Test1.sql"); // Tabelle neu erzeugen
              q->ExecSQL();

              int rd;
              TDateTime Start = TDateTime::CurrentDateTime();
              q2->RequestLive = true;
              q2->Prepare();
              q2->Open();
              for (int i = 0; i < 200000; i++)
              {
              q2->Insert();
              q2Feld1->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld2->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld3->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld4->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld5->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld6->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld7->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld8->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld9->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld10->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld11->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld12->AsString = AnsiString(i + rd);
              rd = RandomRange(1,50000);
              q2Feld13->AsString = AnsiString(i + rd);
              q2->Post();

              }
              if (q2->Active)
              q2->Close();
              if (q2->Prepared)
              q2->UnPrepare();
              q2->RequestLive = false;
              TDateTime Ende = TDateTime::CurrentDateTime();
              RichEdit1->Lines->Add("Laufzeit: " + TDateTime((double) (Ende.Val - Start.Val)).TimeString());

              Start = TDateTime::CurrentDateTime();
              q->SQL->Text = "CREATE INDEX test1 ON \"test.db\" Feld1";
              q->ExecSQL();
              Ende = TDateTime::CurrentDateTime();
              RichEdit1->Lines->Add("index Feld1: " + TDateTime((double) (Ende.Val - Start.Val)).TimeString());

              Start = TDateTime::CurrentDateTime();
              q->SQL->Text = "CREATE INDEX test2 ON \"test.db\" Feld1, Feld2";
              q->ExecSQL();
              Ende = TDateTime::CurrentDateTime();
              RichEdit1->Lines->Add("Index Feld1 und Feld2: " + TDateTime((double) (Ende.Val - Start.Val)).TimeString());


              Start = TDateTime::CurrentDateTime();
              q->SQL->Text = "CREATE INDEX test3 ON \"test.db\" Feld3, Feld4";
              q->ExecSQL();
              Ende = TDateTime::CurrentDateTime();
              RichEdit1->Lines->Add("Index Feld3 udn Feld4: " + TDateTime((double) (Ende.Val - Start.Val)).TimeString());
              </PRE>

              Die Ausgabe im RichEdit:<BR>
              Laufzeit: 00:00:10<BR>
              index Feld1: 00:00:07<BR>
              Index Feld1 und Feld2: 00:00:07<BR>
              Index Feld3 udn Feld4: 00:00:07<BR>

              Ich habe das mehrfach ausprobiert, immer die gleich Laufzeit.<BR>
              Wenn ich die chars aus Zufallszahlen zwischen i plus 1 und 50.000.000 erzeuge:<BR>
              Laufzeit: 00:00:10<BR>
              index Feld1: 00:00:08<BR>
              Index Feld1 und Feld2: 00:00:09<BR>
              Index Feld3 udn Feld4: 00:00:09<BR>

              Ich habe TQuery und TDataSource verwendet. BDE Version 5.11.

              Grüße Joche

              Comment


              • #8
                Das liest sich natürlich sehr interessant, vor allem weil Du die BDE 5.11 verwendet hast. Damit habe ich ja noch viel schlechtere Ergebnisse erreicht, wie oben für ADO aufgeführt

                Comment


                • #9
                  Na, ja während ich das hier probiert habe, sind die beiden Postings vor meinem dazu gekommen. Da steht was von 450 MHz Rechner - ich hab' das hier auf einem AMD XP 2400, Win XP Pro getestet. Aber wir haben hier auch irgendwo einen 450er mit NT 4. Das Ergebnis reiche ich später nach...

                  Joche

                  Comment


                  • #10
                    Ergebnis auf 450MHz PIII / NT 4:<BR>
                    Laufzeit: 00:01:16<BR>
                    index Feld1: 00:00:38<BR>
                    Index Feld1 und Feld2: 00:00:39<BR>
                    Index Feld3 und Feld4: 00:00:40<BR>

                    Dauert zwar schon deutlich länger, aber insgesamt immmer noch unter 3 1/2 Minuten...

                    Also die BDE ist es anscheinend nicht.

                    Grüße Joche

                    Comment


                    • #11
                      Hallo,
                      das wären ja Zeiten mit denen ich leben könnte. Nur sind die Kunden durch die Delphi/Fox Lösung verwöhnt, besser werden muß es nicht, aber deutlich schlechter darf es eben nicht werden.
                      Merkwürdig ist schon, daß das offensichtlich nur in Delphi so ist, ich werde mal versuchen mit Hilfe des C++ Builders das zu realisieren, aber das wird wohl keine Besserung bringen.

                      Dank

                      Comment


                      • #12
                        Hallo Peter,<BR><BR>dein Code fängt ja an mit:<BR>ADOTable1.Open;<BR>Also muss die verschlüsselte Datei in diesem Moment schon über ADO lesbar sein. Welchen Provider benutzt du denn? Wenn es die Jet-Engine ist, dann versuche doch mal die oben gezeigte Syntax. Du wirst erstaunt sein wie schnell der Import geht! Von ihr werden Access, dBase, Paradox, Excel, Text und HTML(definierte Form) direkt unterstützt!<BR><BR>Viele Grüße Ola

                        Comment


                        • #13
                          Die Daten werden in einer Schleife auseinandergedröselt und dann gespeichert. Wenn es helfen würde, kann ich die natürlich auch erst in eine Textdatei schreiben.
                          Ich werde das in der übernächsten Woche auf jeden Fall ausprobieren. Leider bin ich in Urlaub geschickt worden :-)

                          Danke für alle Tips

                          Bin für alle weiteren Tips dankbar

                          Comment


                          • #14
                            Hallo,

                            in meinem Buch <i>ADO und Delphi</i> beschäftigen sich die Seiten 87 bis 96 mit Performance-Vergleichen zwischen ADO und der BDE. Wie die Tabellen 1.13 bis 1.17 zeigen, muss sich ADO in keinster Weise hinter der BDE verstecken. Allerdings unterstützt ADO sehr viele Zugriffswege, wobei es langsame und schnelle gibt. Für das Einfügen von 1000 Datensätzen benötigt <b>TADOCommand</b> nur 1 Sekunde (lokale MS SQL Server 2000-Tabelle). Das direkte Hantieren mit dem nativen <b>Command</b>-Objekt von ADO bei der Kapselung in eine Transaktion drückt diese Zeit auf 0,5 Sekunden.

                            Hinter <b>TADOTable</b> steckt eine von Borland so genannten "Kompatibilitäts-Komponente", deren Daseinsberechtigung nur kurzzeitig während der Umstellung von der BDE nach ADO vorhanden ist. In einem "richtigen" Programm hat diese Krücke nichts zu suchen :-

                            Comment


                            • #15
                              Angeregt durch diese Diskussion habe ich ein Delphi-Programm geschrieben mit dem sich (ohne großen Aufwand zu betreiben) die Geschwindigkeit zwischen ADO + Jet und IBX + InterBase vergleichen läßt. Falls jemand daran Intresse hat, kann er es hier http://www.sebhen.de/~shenrich/CmpJetIB.zip herunterladen. Wenn jemand den Quellcode haben will, kann er den direkt von mir bekommen.

                              Aufgrund der Werte, welches mir das Programm ausgibt, müsste sich das Vorhaben sowohl mit Interbase als auch mit ADO + Jet in den zeitlichen Vorgaben verwirklichen lassen.

                              Gruß

                              Sebastia

                              Comment

                              Working...
                              X