Code mit Datenbankzugriffen und Berechnungen ist langsam

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Unsere Datenschutzerklärung wurde aktualisiert. Mit der Nutzung unseres Forums akzeptierst Du unsere Datenschutzerklärung. Du bestätigst zudem, dass Du mindestens 16 Jahre alt bist.

    • Code mit Datenbankzugriffen und Berechnungen ist langsam

      Ich arbeite mit einer Firebird Datenbank, die mittlerweile etwas größer geworden ist. Weil da häufig Neuberechnungen anstehen, die dann relativ viele Datensätze betreffen, wird die Berechnungszeit mittlerweile recht hoch - obwohl das Ding auf einem Gamer-PC mit SSD Laufwerk läuft, rechnet der ab und zu mal ne viertel bis halbe Stunde.... Könnt ihr mir mal nen Tip geben, welche Aktionen im Code unten zeitkritisch sind?

      Quellcode

      1. whileloop i%
      2. Y$ = GetText$(hTabelle&,&Loop-1,0)
      3. clearlist hGrid&
      4. X$ = "SELECT MKey, MTyp, MDatum, MText, MWert1, MWert2, MPreis, MPrim From MAT WHERE MPrim = '" + Y$ + "'"
      5. i% = @db("fbSQLExec", ep&, X$, hGrid&)
      6. Text$= GetText$(hGrid&,0,3) '
      7. SetText DText&[8], str$(x%+1) + " Strings zu bearbeiten, bearbeite: "+Text$
      8. Key$ = GetText$(hGrid&,0,0)
      9. faktor! = val(GetText$(hGrid&,0,4))
      10. summe! = faktor! * ep!
      11. X$ = "UPDATE MAT SET MPreis='"+str$(summe!)+ "' ,MDatum = '"+ Date$(0) + "' WHERE MPrim = '" + Y$ + "'"
      12. db("fbSQLExec", ep&, X$,1)
      13. X$ = "SELECT SUM(MPreis) FROM MAT WHERE MTyp = 'B' AND MKey = '"+ Key$ +"'"
      14. @db("fbSQLExec", ep&, X$,hGrid&)
      15. summe! = val(@GetText$(hGrid&,0,0))
      16. faktor! = 0
      17. X$ = "SELECT MWert1 FROM MAT WHERE MTyp = 'O' AND MKey = '"+ Key$+"'"
      18. @db("fbSQLExec", ep&, X$,hGrid&)
      19. faktor! = val(@GetText$(hGrid&,0,0))
      20. if faktor! > 0
      21. summe! = summe! / faktor!
      22. endif
      23. X$ = "UPDATE MAT SET MPreis='"+str$(summe!)+ "' ,MDatum = '"+ Date$(0) + "' WHERE MTyp = 'O' AND MKey = '"+ Key$+"'"
      24. db("fbSQLExec", ep&, X$,1)
      25. AddString Key$
      26. endwhile
      Alles anzeigen
      ---
      Xprofan X4, Win7/32, Win10/64
    • Hi Martin,
      setz mal nach jeder db(fbSQLExec......) Zeile ein Print "db(fbSQLExec......) " + die Uhrzeit mit Sekunden.

      Und auch nach dieser Zeile:
      5. i% = @db("fbSQLExec", ep&, X$, hGrid&)

      Und auch1x vor Zeile 1 die Zeit nehmen.
      Und 1x nach der Schleife..

      So kannst du ziemlich gut erkennen, an welcher Stelle Firebird so lange hängt.
      Und dann schaun wir mal...
      Gruß Jörg

      Ideen gibt es viele - man muß sie nur haben...
      Win7-Pro / Linux Mint
    • Mehr eine theoretische Anleitung:
      Vor der ersten DB-Anweisung ein Set Transaktion und am Ende ein Commit (siehe Anleitung für Firebird) Transaktions-Statements.
      Dies verhindert, das nach jeder Änderung in die DB geschrieben wird. Dies geschieht erst am Ende, was einen erheblichen Geschwindigkeitsvorteil bringt.

      Wie das jetzt in XProfan umzusetzen ist, da sollte dann jemand anders helfen :pfeifend:
      Gruß Thomas

      "Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."
      ComputerInfo für PPF
    • Zitat aus der Hilfe:

      Transaktionen:
      Normalerweise wird bei Firebird jeder SQL-Befehl sofort und endgültig ausgeführt, was in 90% aller Fälle auch korrekt ist. Aber es gibt Fälle, wo mehrere Datenbankanweisungen nur komplett oder überhaupt nicht ausgeführt werden sollen. Hier greifen die Transaktionen mit folgenden Befehlen:
      db("fbExec", "#TRANSACTION", N%)
      db("fbExec", "#COMMIT",N%)
      db("fbExec", "#ROLLBACK",N%)
      Eine Transaktion wird entweder komplett ausgeführt oder gar nicht. Im Normalzustand ist der Autotransaktionsmodus eingeschaltet: Jeder SQL-Befehl ist eine eigene Transaktion. Mit TRANSACTION kann man dies abschalten. Alle folgenden Befehle sind nun zusammen eine Transaktion, bis sie mit einem "COMMIT" bestätigt und endgültig ausgeführt oder mit "ROLLBACK" verworfen werden. Alle Änderungen in den Datentabellen vor "COMMIT" sind nur temporär und werden im Falle eines "ROLLBACK" wieder zurückgenommen.
      Nach COMMIT oder ROLLBACK wird der Autotransaktions-Modus wieder eingeschaltet: Jeder SQL-Befehl ist wieder eine eigene Transaktion.
      SQLDONE beendet etwaige offene Transaktionen mit einem COMMIT.
      Sollte während einer Transaktion ein schwerer Fehler auftreten (Client-Rechner stürzt ab, SQL-Verbindung zum Server bricht ab, etc.), führt die Datenbank in aller Regel ein automatisches ROLLBACK durch.

      Und ja, das wird das Ganze extrem beschleunigen. Außerdem macht es die Daten sicherer, da bei einem Fehler im Ganzen eben nichts geändert wird.

      Gruß
      Roland
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • nur um das technisch besser zu verstehen - die Sicherheit liegt ja auf der Hand. Soweit, so klar.
      Jedoch wie kommt es zu der höheren Geschwindigkeit?
      Wenn der Server erstmal alles temporär ausführen muß (und sich den Ausgangszustand merkt) und dann zusätzlich beim COMMIT die DB-Änderungen entgültig ausführt, ist das ja unterm Strich mehr Arbeit für den Server - sollte also demnach eher langsamer werden.
      Wodurch wird er aber nun schneller?

      Es sei denn, die temporären Änderungen werden alle vorerst rein im RAM (falls ausreichend vorhanden) ausgeführt und dann am Ende genau 1x auf SSD geschrieben.
      Schont ja dann gleich nebenbei die SSD :-)
      Gruß Jörg

      Ideen gibt es viele - man muß sie nur haben...
      Win7-Pro / Linux Mint

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von JörgG ()

    • Jede Änderung stellt eine Transaction dar und wird mit einem auto-commit (schreiben in die DB) beendet. Mit Set Transaction wird dieser auto-commit nicht mehr ausgeführt, sondern erst wenn der Befehl commit kommt. Commit ist also nicht zusätzlich! Es werden mehrere Aktionen zusammengefaßt und dann in einem Rutsch in die DB geschrieben.
      Gruß Thomas

      "Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."
      ComputerInfo für PPF
    • soweit verstanden. Aber dieses "Zusammenfassen" wird ja zuvor temporär ausgeführt und erst mit commit schließlich in einem Rutsch in die DB geschrieben (quasi das Endergebnis).
      Das dann der eine Rutsch schneller geht, als etliche Male die DB neu zu schreiben, ist auch verstanden.

      Mir ging es eher um den temporären Part, der ja auch irgendwie zwischengespeichert werden muß (je nachdem, welche SQL-Aktionen abgewickelt werden)
      Und das kann ja eigtl. nur im RAM passieren, sonst wär der Geschwindigkeitsvorteil ja wieder dahin (nach meinen Verständnis zumindest ;-))
      Gruß Jörg

      Ideen gibt es viele - man muß sie nur haben...
      Win7-Pro / Linux Mint