Ankündigung

Einklappen
Keine Ankündigung bisher.

Komplexe MySQL-Abfrage

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Komplexe MySQL-Abfrage

    Guten Tag Zusammen,

    ich stelle mir grad die Frage, wie ich möglichst eine performante Anfrage erstellen kann.

    Ich möchte gerne einen Report erstellen in der alle Bestellungen (Kopf) mit allen Artikeln dargestellt werden.

    Beispielausgabe:
    Bestellung 1 mit den Bestelldetails...
    Artikel 23, Menge 200, Preis...
    Artikel 45, Menge 200, Preis...
    Artikel 11m Menge 200, Preis...
    Bestellung 2 mit den Bestelldetails...
    Artikel 23, Menge 200, Preis...
    Artikel 45, Menge 200, Preis...
    Artikel 11m Menge 200, Preis...

    Tabellen:
    Bestellung
    BestellungArtikel
    Artikel
    ArtikelDetails
    usw.

    Nun gibt es ja verschiedene Möglichkeiten an alle Daten zu kommen:
    1) Query in Query (foreach-Schleifen)
    2) MEGA-Abfrage mit JOINS
    3) Subquerys

    Was ist am schnellsten?

    Weiterhin stellt sich mit die Frage ob ich erstmal alle Ergebnisse in ein Array zwischenspeichere und diese dann zum Ausgeben zu durchlaufen oder ob es Sinn macht alles direkt auszugeben?


    Viele Grüße,
    John


  • #2
    Daumenregel: Was die Datenbank kann solltest du sie machen lassen. Insbesondere wenn es dir um Performance geht.

    Mit Php drüberschleifen ist aufjedenfall nicht performant, jenachdem wieviele Datensätze du hast, aber ggf. auch vollkommen ausreichend.

    Wenn da am Ende das exakt gleiche Ergebnis rauskommt, würde ich vermuten, dass sich 2 und 3 nicht viel nehmen, da sollte dann die Optimierung von MySQL beide Male die gleiche Abfrage drauß machen. Im Zweifel solltest du aber Joins den Subqueries vorziehen. Demach wäre 2 vermutlich die beste Lösung.

    Kommentar


    • #3
      Zitat von JohnWorks Beitrag anzeigen
      Guten Tag Zusammen,

      ich stelle mir grad die Frage, wie ich möglichst eine performante Anfrage erstellen kann....

      Nun gibt es ja verschiedene Möglichkeiten an alle Daten zu kommen:
      1) Query in Query (foreach-Schleifen)
      2) MEGA-Abfrage mit JOINS
      3) Subquerys

      Was ist am schnellsten?

      Weiterhin stellt sich mit die Frage ob ich erstmal alle Ergebnisse in ein Array zwischenspeichere und diese dann zum Ausgeben zu durchlaufen oder ob es Sinn macht alles direkt auszugeben?


      Viele Grüße,
      John
      Selbstverständlich ist Lösung 2 die bei weitem beste. Ich weiß ehrlich gesagt auch nicht, warum du die "Mega-Abfrage nennst". Du benötigst etwa 6 Tabellen, bspw. bestellkopf, bestellposition, artikel, artikel_preis, kunde...

      Wie LudwigBr bereits schrieb: Was die Datenbank kann solltest du sie machen lassen. Dafür ist sie gemacht. Und JOINS sind nunmal auch erfunden worden, weil sie performanter als Subquerys sind.

      Die Frage mit dem array verstehe ich nicht. Du willst einen Bericht erstellen, also frage alles mit einer Abfrage ab und arbeite Sie mit Gruppenwechsel ab. Das als einfach html-Tabelle aber schön übersichtlich ist eine Sache von 1 std., korrektes Datenmodell vorausgesetzt.

      Kommentar


      • #4
        Zitat von JohnWorks Beitrag anzeigen
        Weiterhin stellt sich mit die Frage ob ich erstmal alle Ergebnisse in ein Array zwischenspeichere und diese dann zum Ausgeben zu durchlaufen oder ob es Sinn macht alles direkt auszugeben?
        fetchAll sollte immer schneller sein, belegt aber natürlich auch mehr Arbeitsspeicher als fetch in einer Schleife. (Falls das die Frage war)

        Zitat von LudwigBr Beitrag anzeigen
        da sollte dann die Optimierung von MySQL beide Male die gleiche Abfrage drauß machen.
        Ist das wirklich so? Hast du Details zu diesem Feature?
        sorry, shift-taste kaputt

        Kommentar


        • #5
          Zitat von Meister1900 Beitrag anzeigen
          Ist das wirklich so? Hast du Details zu diesem Feature?
          Ich bin da nicht unabsichtlich vage geblieben.
          Ob dem wirklich so ist und wie mächtig die Optimierung ist, kann ich dir nicht sagen. Ich weiß, dass eine Optimierung existiert, aber ansonsten habe ich nicht viel mit MySQL am Hut.
          https://dev.mysql.com/doc/internals/en/optimizer.html

          Kommentar


          • #6
            Es gibt keine SQL Features, die aus sowas einen "Selbstläufer" machen. Performance sollte kein Problem sein, es wird einfach alles gejoint und nach Bestellung gruppiert. Da gibt es nichts zu optimieren, wenn das Datenmodell und die Indizes okay sind.*
            Damit erhält man dann offensichtlich eine "große" Tabellenausgabe, wo der Bestellkopf als Spalte durchgehend mitläuft, sich also pro Bestellposition wiederholt.
            Die muss man im Report bei der Ausgabe durchprüfen und entsprechend abfangen und layouten, also Bestelldaten nur einmalig anzeigen bei Wechsel, dann ausblenden.

            Wenn man möchte, kann man das "Abfangen" und "Ausblenden" auch per SQL machen. Das ist etwas komplexer, Stichwort Window Functions (ab mysql 8 oder woanders schon länger).

            Eigentlich nutzt man für sowas Reportmodule, die auf solche Aufgabenstellungen spezialisiert sind. Denen gibt man Kopf- und Laufdaten Queries und definiert typischerweise oft auch Summen-Elemente. Dazu bestimmt man für die Elemente die Verknüfungsangaben (Join Felder).

            *Vermutlich werden ja nie alle Bestellungen reportet, sondern eine Auswahl wie "offen", "letzte 30 Tage", "heute verpackt", "heute versendet" oder sowas. Sobald man Summen / Aggregat Felder hinzunimmt, muss der ganze Kram ja u.U. gruppiert werden, was bei großen Mengen dann eben doch etwas kosten kann.

            @Optimizer: Subqueries, als Abfragen die in der Select Clause aufgerufen werden, sind idr. nicht gut optimiert. Ich kann da keine Details zu nennen, erst Recht nicht bei mysql.
            Ich sehe aber hier gar keinen Grund sie einzusetzen.

            Kommentar


            • #7
              Erstmal vielen Dank!

              Ich werde es mit einer Abfrage umsetzen. Kann ich die Tabellenköpfe in der Abfrage einbauen? Ich habe eine Liste mit allen Artikel...
              ​​
              Zitat von Perry Staltic Beitrag anzeigen
              Eigentlich nutzt man für sowas Reportmodule, die auf solche Aufgabenstellungen spezialisiert sind. Denen gibt man Kopf- und Laufdaten Queries und definiert typischerweise oft auch Summen-Elemente. Dazu bestimmt man für die Elemente die Verknüfungsangaben (Join Felder).
              Hast du einen Tipp für ein schlankes Reportmodule, dass nicht direkt ein riesiges Framework mitbringt??

              Kommentar


              • #8
                Zitat von JohnWorks Beitrag anzeigen
                Erstmal vielen Dank!

                Ich werde es mit einer Abfrage umsetzen. Kann ich die Tabellenköpfe in der Abfrage einbauen? Ich habe eine Liste mit allen Artikel...
                ​​


                Hast du einen Tipp für ein schlankes Reportmodule, dass nicht direkt ein riesiges Framework mitbringt??
                Hast du denn eine konkrete Vorstellung davon, wie dieser Report aussehen soll? Es wird doch im weitesten Sinne eine HTML-Tabelle sein. Dazu brauchst du doch kein vorgefertigtes "Reportmodule".

                Erg. (erg.):
                Wie du die Spaltennamen aus dem Assoz. Array ausliest, findest du hier: https://www.php.net/manual/de/function.key.php

                Das kannst du mit msqli prozedural oder oo. ausgeben lassen oder mit pdo. Es besteht aber in allen Varianten die Mögl., ein assoz. Array ausgeben zu lassen.

                Kommentar

                Lädt...
                X