.MB: PDO oder SQL Statement

Mahlzeit,

ich möchte eine Datenbank auslesen. Ich will wissen welche vorgehensweise performanter ist

  • komplexe PDO Statements mit wenig SQL da die Daten mit PDO gefiltert werden (ich nehme an das die größer ungefilterten Daten nicht zusätzlich viel Rechenzeit fressen)
  • oder wenig PDO Statments daher mit komplexcen verschachtelten SQL Befehlen um das gleiche Ergebnis zu erzielen

Anmerkung: ich kenne mich in Sachen Datenbank und PDO nicht so gut aus.

LG MB

  1. Hallo .MB,

    • komplexe PDO Statements mit wenig SQL da die Daten mit PDO gefiltert werden (ich nehme an das die größer ungefilterten Daten nicht zusätzlich viel Rechenzeit fressen)
    • oder wenig PDO Statments daher mit komplexcen verschachtelten SQL Befehlen um das gleiche Ergebnis zu erzielen

    Ich bin nicht sicher, was du meinst, wenn du von „da die Daten mit PDO gefiltert werden“ meinst. Aber prinzipiell kann ich dir sagen, dass die Datenbank effizienter ist bei der Filterung von Result-Sets als wenn du das in deinem Code machst; viele Shortcuts (Indizes, Index-Only-Scans, …) kannst du gar nicht gehen, da bei einer Filterung in deinem Programm die Daten sowieso von der Platte gelesen, serialisiert und wieder deserialisiert werden müssen. Deshalb würde man allgemein immer den Rat geben, so viel wie Möglich in der Datenbank zu erledigen und lieber schauen, wie man das schnell bekommt als das in den Code zu verlagern.

    Es mag allerdings auch Gegenbeispiele geben.

    LG,
    CK

    1. hi,

      Es mag allerdings auch Gegenbeispiele geben.

      es kommt auch auf die Datnmenge an. Nehmen wir mal eine Webpräsenz mit 500 Unterseiten wobei die Templates dafür samt Eigenschaften wie title, descr, class usw. in einer Datei auf der Festplatte liegen. Diese Datei (ca 1MB) ist schneller in den RAM gelesen als ein PDO erstellt wird, der für eine einzige Seite die Daten samt Body-Template aus MySQL beschaffen zum Ziel hat. MfG

      1. Hallo pl,

        Es mag allerdings auch Gegenbeispiele geben.

        es kommt auch auf die Datnmenge an.

        Natürlich. Das schrieb ich ja. Aber nicht so, wie du es vermutlich meinst.

        Nehmen wir mal eine Webpräsenz mit 500 Unterseiten wobei die Templates dafür samt Eigenschaften wie title, descr, class usw. in einer Datei auf der Festplatte liegen. Diese Datei (ca 1MB) ist schneller in den RAM gelesen als ein PDO erstellt wird, der für eine einzige Seite die Daten samt Body-Template aus MySQL beschaffen zum Ziel hat.

        Ist deine Aussage, dass eine 1MB-Datei schneller ausgelesen ist als die Daten aus einer MySQL-Datenbank in einer vergleichbaren Größe?

        Wenn ja (der Wahrheitsgehalt sei dahin gestellt, das ist komplizierter als man glaubt): was hat das mit der ursprünglichen Frage zu tun? Deine Antwort kommt mir vor wie eine Aussage der Art „Des Nachts ist es kälter als draußen.“

        LG,
        CK

        1. Freu dich doch, dass Du mal ein paar Zahlen aus erster Hand bekommst. Ich habe auch die Erfahrug gemacht, dass es performanter ist, eine ganze MySQL-Tabelle als Array komplett in den RAM zu lesen, anstatt mit prepared Statements einzelne Records abzufragen. Ich unterstütze damit DEINE Aussage, ist Dir das eigentlich klar!?

          1. Hallo pl,

            Freu dich doch, dass Du mal ein paar Zahlen aus erster Hand bekommst.

            Hehe, aber mir Arroganz vorwerfen ;-)

            Ich habe auch die Erfahrug gemacht, dass es performanter ist, eine ganze MySQL-Tabelle als Array komplett in den RAM zu lesen, anstatt mit prepared Statements einzelne Records abzufragen.

            Diese Aussage ist dermaßen allgemein, dass ihr Wahrheitsgehalt nicht überprüfbar ist. Klar kann es sein, dass es schneller ist eine Tabelle komplett zu holen, aber das muss nicht sein - das hängt von vielen Faktoren ab (unter anderem: Anwendungsfall - was will ich mit den Daten machen? - und Menge der Daten). Und auch dann sind andere Constraints zu bedenken: würde ich diese Vorgehensweise z.B. mit unserer Erreichbarkeit anstreben, dann würden die Daten gar nicht in den RAM passen.

            Ich unterstütze damit DEINE Aussage, ist Dir das eigentlich klar!?

            Meine Aussage war eine völlig andere.

            LG,
            CK

            1. Hallo Christian Kruse,

              unsere Erreichbarkeit

              OT: Ist ss statt ß Absicht?

              Bis demnächst
              Matthias

              --
              Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
              1. Hallo Matthias,

                unsere Erreichbarkeit

                OT: Ist ss statt ß Absicht?

                Nein, ein Fehler ;) Danke.

                LG,
                CK

                1. Hallo Christian Kruse,

                  OT: Ist ss statt ß Absicht?

                  Nein, ein Fehler ;) Danke.

                  Zwei ;)

                  Bis demnächst
                  Matthias

                  --
                  Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
          2. Ich habe auch die Erfahrug gemacht, dass es performanter ist, eine ganze MySQL-Tabelle als Array komplett in den RAM zu lesen, anstatt mit prepared Statements einzelne Records abzufragen.

            tl-dr: es kommt immer auf die Lage an. Man kann das nicht so allgemein sagen wie Du es schreibst.

            Ich würde vermuten, dass ein Full Table Read nur in Ausnahmefällen lohnt. Ok, ich habe es auch schon gemacht, aber nur, weil ich einen dusseligen DB Layer hatte (.NET EntityFramework) der unbedingt SQL generieren wollte und dieses SQL einfach nicht situationsangemessen war.

            Grundsätzlich gilt dabei:

            • Die Tabelle muss in den RAM passen
            • Wenn es ein Web ist, musst Du entweder in EINEM REQUEST sehr viele Zugriffe auf die Tabelle machen, damit sich das lohnt, oder du brauchst ein Cache Tool (APC? Habs noch nicht genutzt). Bei Einsatz eines Cache bekommst Du einen ganzen Haufen neuer Probleme bezüglich Aktualität.
            • Selbst wenn die Tabelle passt, kostet das RAM, den bei vielen aktiven Usern der Webserver, die PHP Runtime oder andere Komponenten dringender brauchen könnten.

            Gruß Rolf

      2. Hallo pl

        es kommt auch auf die Datnmenge an. Nehmen wir mal eine Webpräsenz mit 500 Unterseiten wobei die Templates dafür samt Eigenschaften wie title, descr, class usw. in einer Datei auf der Festplatte liegen. Diese Datei (ca 1MB) ist schneller in den RAM gelesen als ein PDO erstellt wird, der für eine einzige Seite die Daten samt Body-Template aus MySQL beschaffen zum Ziel hat.

        War auch meine überlegung und Frage die du beantwortet hast. In dem Fall Danke ich Dir für die AW.

        VLG MB

    2. Hallo CK,

      Ich bin nicht sicher, was du meinst, wenn du von „da die Daten mit PDO gefiltert werden“ meinst. Aber prinzipiell kann ich dir sagen, dass die Datenbank effizienter ist bei der Filterung von Result-Sets als wenn du das in deinem Code machst;

      Das war meine Frage ;-)

      Deshalb würde man allgemein immer den Rat geben, so viel wie Möglich in der Datenbank zu erledigen und lieber schauen, wie man das schnell bekommt als das in den Code zu verlagern.

      Besten Dank

      LG MB

  2. Abend,

    ich hab noch vergessen zu erwähnen das ich gern SQL in einer separaten Classe gespeichert haben will

    z.B.: SQL.cfg.php

    class cfgSQL
    {
      private
        getUsers = '
          SELECT *
          FROM tbl_users;
        ';
      
      public function getUsers() {
        return $this->getUsers;
      }
    }
    

    dann nur noch in eine PDO-Abfrage implementieren

    z.B.: DB.inc.php

    class DB extends PDO
    {
      public function getSQL( $SQL ) {
        // ...
      }
    }
    

    Und dann ebend aufrufen

    include( 'SQL.cfg.php' );
    include( 'DB.cfg.php' );
    include( 'DB.inc.php' );
    
    $cfgSQL = new $cfgSQL();
    $cfgDB = new $cfgDB();
    $db = new $DB( $cfgDB->getDSN(), ...);
    
    $users = $db->getSQL( $cfgSQL->getUsers );
    

    wäre das so ok?

    bitte um Feedback

    MFG mb

    1. Hallo MB,

      z.B.: SQL.cfg.php

      class cfgSQL
      {
        private
          getUsers = '
            SELECT *
            FROM tbl_users;
          ';
        
        public function getUsers() {
          return $this->getUsers;
        }
      }
      

      dann nur noch in eine PDO-Abfrage implementieren

      z.B.: DB.inc.php

      class DB extends PDO
      {
        public function getSQL( $SQL ) {
          // ...
        }
      }
      

      Und dann ebend aufrufen

      include( 'SQL.cfg.php' );
      include( 'DB.cfg.php' );
      include( 'DB.inc.php' );
      
      $cfgSQL = new $cfgSQL();
      $cfgDB = new $cfgDB();
      $db = new $DB( $cfgDB->getDSN(), ...);
      
      $users = $db->getSQL( $cfgSQL->getUsers );
      

      wäre das so ok?

      Das erscheint mir zu kompliziert und overengineered. Ausserdem ist es schlecht lesbar, ich sehe vom Code lesen nicht, welches SQL dort ausgeführt wird. Erschwerend hinzu kommt, dass es von dieser Struktur nur noch ein kleiner Schritt zu einem ORM ist - warum also nicht sofort ein ORM verwenden? Im PHP-Ökosystem dürfte das bekannteste vermutlich Doctrine sein. Ein weiteres sehr bekanntes ist Propel.

      LG,
      CK

    2. Das nennt man "Repository Pattern" und ist durchaus ok :)

      Es ist mMn allerdings nicht unbedingt nötig, für die SQLs eine private Variable und eine Zugriffsfunktion anzulegen, da würde ich einfach statische Variablen draus machen.

      Eventuell musst Du dabei aber über die Verantwortlichkeiten der Klassen nachdenken.

      • Ein User-Repository liefert Dir User. Der Nutzer des User-Repository interessiert sich nicht für SQL und sollte dem Repository daher kein SQL liefern müssen.
      • Du wirst mehrere Daten-Domänen in deiner Anwendung haben. Normalerweise baut man pro Domäne ein Repository.
      • Um im fachlichen Code ein Repository zu bekommen, wendet sich der fachliche Code an eine Repository-Factory. Die initialisiert bei der ersten Bestellung die DB-Anbindung. Sie erzeugt jedes Repository genau einmal und cached es dann. D.h. wenn Du 5 mal ein User-Repository anforderst, bekommst Du jedes Mal das gleiche Objekt.
      • Wenn Du gerne Repository und SQL Container in separaten Klassen haben willst, wäre es dann auch Aufgabe der Factory, das zusammenzustöpseln, ohne dass Du es in deinem problembezogenen Code zu sehen bekommst.

      Codebeispiele lass ich erstmal weg - wenn Du dazu mehr wissen willst sag Bescheid.

      Gruß Rolf

    3. nabend Rolf, CK,

      WOW sehr viele fachbegriffe habt ihr da. Ich lesen grade Galileo - Objektorientierte Programmierung über OpenBook und da bekomme ich einige Fachbegriffe und Heragehensweisen durch das Buch beigebracht. Ich öffne mal ne neuen Thread und werde nach Lehrbüchern Büchern fragen.

      Schönen Abend wünsche ich euch in diesem Thread

      VGL MB

      1. Ja, solly. Leidel altet sowas immel gelne in Fachchinesisch aus.

        Das Schlimme an der OOP ist, dass sie nur das Fundament darstellt und die wahre Kunst darin liegt, sein Programm schlau auf Klassen zu verteilen. Zum einen entwickelt sich das ständig weiter, so dass alle 2-3 Jahre ein

        brain.reset()
        

        unvermeidlich ist, und das, was sich entwickelt hat, ist sehr schwer überschaubar. Die wichtigen Stichworte sind hier "design patterns" (Entwurfsmuster) und "clean code".

        Gruß Rolf