Announcement

Collapse
No announcement yet.

SUM-Befehl sehr langsam

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

  • SUM-Befehl sehr langsam

    Hallo,

    ich greife aus einem Delphi-Programm über "Microsoft OLE DB Provider for ODBC Drivers" und den ODBC-Treiber von MySQL auf eine MySQL-Datenbank zu. Befehle mit Aggregat-Fubktionen (z.B. SUM) laufen dabei sehr langsam. Ich habe daher im SQL-Log von MySQL die Befehle protokollieren lassen und festgestellt, dass bei einem Befehl der Art

    select SUM(Preis) as Gesamtpreis from Orders where Client_ID=4711

    zusätzlich ein Befehl

    select * from Orders

    im SQL-Log auftritt, der so nie im Programm zu finden ist. Wenn viele Daten vorhanden sind, ist das natürlich tödlich.

    Ich kann das nur so deuten, dass der ODBC-Treiber oder der OLE-Treiber den SUM-Befehl so "interpretiert", dass zuerst alle Daten geholt werden (daher "select * from Orders") und diese dann durchforstet werden, um bei passendem Wert von Client_ID die Daten in die Summierung aufzunehmen.

    Ich habe dann den gleichen Befehl im guten alten "SQL-Explorer" von Borland eingegeben (wobei ich direkt über ODBC, d.h. ohne den OLD DB-Treiber), dann tauchte im SQL-Log kein zusätzliches "select * from Orders" auf. Das lässt mich vermuten, dass die Ursache im "Microsoft OLE DB Provider for ODBC Drivers" liegt. Hat jemand damit schon mal Erfahrung damit gesammelt? Gibt es eine Lösung für das Problem?

    Da das Programm auf mehrere Datenbanken über ADO zugreifen können soll, ist eine Abkehr vom OLE DB-Treiber kaum möglich.

  • #2
    ADO bietet sich nur für Access und MSSQL an.
    Abhilfe könnte das Auslagern in SPs schaffen

    Comment


    • #3
      Grundsätzlich funktioniert der Zugriff ja auch auf eine MySQL-Datenbank ohne Probleme, nur Aggregat-Befehle machen Ärger.
      Ich werde aber mal darüber nachdenken, diese in Stored Procedures auszulagern.

      Comment


      • #4
        Originally posted by Jürgen Richter View Post
        ... Ich habe daher im SQL-Log von MySQL die Befehle protokollieren lassen und festgestellt, dass bei einem Befehl der Art

        select SUM(Preis) as Gesamtpreis from Orders where Client_ID=4711

        zusätzlich ein Befehl

        select * from Orders

        im SQL-Log auftritt, der so nie im Programm zu finden ist. Wenn viele Daten vorhanden sind, ist das natürlich tödlich.
        Hört sich für mich an das hier aufgrund er fehlerträchtigen großen Treiberkette
        Anwendung ADOExpress -> ADO -> OLE DB für ODBC -> ODBC -> MySQL-ODBC-Treiber -> Libmysql.dll -> MySQL-Datenbank

        irgendwo etwas zu viel automatismus abläuft.

        Originally posted by Jürgen Richter View Post
        Ich kann das nur so deuten, dass der ODBC-Treiber oder der OLE-Treiber den SUM-Befehl so "interpretiert", dass zuerst alle Daten geholt werden (daher "select * from Orders") und diese dann durchforstet werden, um bei passendem Wert von Client_ID die Daten in die Summierung aufzunehmen.
        Ich tippe eher auf ADOExpress und Automatismus in der Implementierung. Die sonstigen Ebenen sind "SQL-Technisch" dumm.

        Originally posted by Jürgen Richter View Post
        Hat jemand damit schon mal Erfahrung damit gesammelt? Gibt es eine Lösung für das Problem?
        Wie schon gesagt. Schmeiß für MySQL ADO/ODBC weg und besorg dir eine vernünftige direkte Zugriffskomponenten wie z.B. von Core Labs. Damit ist der Stack wie folgt:

        Anwendung -> CoreLabs MySQLDAC -> MySQL-Datenbank

        Originally posted by Jürgen Richter View Post
        Da das Programm auf mehrere Datenbanken über ADO zugreifen können soll, ist eine Abkehr vom OLE DB-Treiber kaum möglich.
        Wieso nicht? Vernünftiges Anwendungsdesign mit Kapslung des DB-Zugriffs z.B. mittels Bridge-pattern kann man mehrer DB native unterstützen. ADO kapselt dir ja auch nicht die SQL-unterschiede.

        Aber wenn du unbedingt dich mit ADO ärgern willst.
        Poste doch mal etwas Code. Auch über ADO ist die unnötige Query nicht zwingend notwendig.

        Comment


        • #5
          Im Anhang habe ich den Quellcode zu einem kleinen Testprogramm beigefügt, daran kann man das von mir geschilderte Verhalten prüfen.

          Voraussetzung: Es existiert eine ODBC-Verbindung mit dem Namen "MYSQL_Test", in der auf eine existierende MYSQL-Datenbank verwiesen wird. Benutzername und Kennwort müssen in der ODBC-Verbindung angegeben werden. Außerdem muss über die Konstante "Pfad_zu_MYSQL_Log" definiert werden, wo sich die Log-Datei von MySQL befindet.

          Das Programm macht folgendes:

          -Beim Start wird eine Tabelle "TEST_1" in der Datenbank angelegt und mit einigen Werten gefüllt (die Tabelle wird bei Beendingung des Programmes wieder gelöscht).

          -Im Programm gibt es ein TDatabase-Objekt und eine TADOConnection-Objekt, mit denen auf die Datenbank zugegriffen wird (über BDE bzw. ADO)

          -Über die beiden Schalter "Aufruf mit BDE" und "Aufruf mit ADO" wird jeweils der gleiche SQL-Befehl (mit einer SUM-Funktion) abgeschickt, in beiden Fällen kommt als Ergebnis 55 raus, was auch korrekt ist.

          -Nach Abschicken des SQL-Befehles werden die letzten 5 Zeilen aus der MYSQL-Logdatei (wo sich diese befindet, muss über die Konstante "Pfad_zu_MYSQL_Log" definiert werden) angezeigt. Bei "Aufruf mit BDE" (wobei direkt die ODBC-Verbindung genutzt wird) erscheint als letzter Befehl in der Log-Datei
          "select sum(MENGE) as GesMenge from TEST_1 where KUNDE_ID=1"
          was auch der im Programm ausgeführte Befehl ist.
          Dagegen erscheint bei "Ausführen mit ADO" (wobei die Kombination "ODBC-Treiber"-"Microsoft OLE DB Provider for ODBC Drivers" verwendet wird) in der Log-Datei "select sum(MENGE) as GesMenge from TEST_1 where KUNDE_ID=1" " (soweit OK), gefolgt aber von "SELECT * FROM TEST_1" ( was so nicht im Programm steht).
          Attached Files
          Zuletzt editiert von Jürgen Richter; 16.02.2008, 23:28.

          Comment


          • #6
            Hier noch eine weitere Erfahrung:

            Wenn ich statt der Kombination "OBBC"-"Microsoft OLE DB Provider for ODBC Drivers" in meinem Testprogramm einen "MySQL OLE DB Provider" benutze, erscheint die Zusatzzeile "SELECT * FROM TEST_1" nicht mehr am Ende des SQL-Logs. Das lässt mich vermuten, dass die Ursache tatsächlich der "Microsoft OLE DB Provider for ODBC Driver" ist. Allerdings ist der "MySQL OLE DB Provider" in der Praxis kaum brauchbar (außer bei ganz einfachen Fällen erhalte ich jede Menge Fehlermeldungen), so dass er keine Alternative darstellt.

            Comment

            Working...
            X