2 Stimmen

Aggregation Wiederholung vs. Geschachtelte Abfrage

Ich habe eine Abfrage wie folgt:

SELECT SUM(`weight`) as totalgrams,
       SUM(`weight`)/1000 as totalkilograms
FROM `item`

für die ich das Ergebnis der ersten Spalte SUM verwenden muss, aber da ich totalgrams nicht verwenden kann, muss ich die SUM-Funktion erneut bei der Berechnung der zweiten Spalte verwenden.
Der Abfrageplan von EXPLAIN: Bildbeschreibung hier eingeben

Jetzt mit der zweiten Abfrage:

SELECT totalgrams, totalgrams/1000 as totalkilograms
FROM (SELECT SUM(`weight`) as totalgrams
       FROM `item`) prequery

Ich muss die SUM nicht wiederholen, aber ich lande mit einer verschachtelten Abfrage.
Der Abfrageplan von EXPLAIN: Bildbeschreibung hier eingeben

Auf den ersten Blick scheint es besser zu sein, die erste Abfrage zu verwenden, da sie nur einen Eintrag im Ausführungsplan hat, aber wurde hier SUM zweimal berechnet (was überflüssig und nicht skalierbar ist)?
Oder hat das System bereits eine Optimierung dafür und berechnet es nur einmal; ist also tatsächlich die erste Abfrage besser?

Aktuell befinden sich nur wenige Zeilen in der Tabelle, daher ist der Unterschied wahrscheinlich nicht signifikant in der realen [ms]-Einheit.
Aber falls es später riesig wird, frage ich mich tatsächlich, welche Abfrage besser wäre?
Und gilt das für alle DBMS?

Es dient ausschließlich dem Verständnis des SQL-Workflows, jeder Einblick ist willkommen.

2voto

Gordon Linoff Punkte 1198148

MySQL materialisiert Unterabfragen im from-Klausel -- der sogenannten abgeleiteten Tabelle. In diesem Fall hat die Zusammenfassung eine Zeile und eine Spalte, also ist es wirklich kein großes Problem.

Das zweimalige Einbeziehen von sum() im select hat keinen Overhead. Aus der Ausgabe des Erklärplans ist nicht klar, ob sum() einmal oder zweimal berechnet wird. Wahrscheinlich zweimal, aber es könnte einen Optimierungsschritt geben, der diese Verarbeitung eliminiert. Jedenfalls ist sum() wirklich billig. Der teure Teil ist die Anordnung der Aggregation, und alle Aggregatfunktionen werden zusammen verarbeitet.

1voto

Billy Bennett Punkte 11

Du sagst, dass dies rein für das Verständnis des Workflows ist, daher werde ich meine Antwort damit beginnen zu sagen, dass mySQL zwar Mittel zur Optimierung dieser Art von Operationen hat und dies auch tun wird, aber es ist nicht perfekt und man sollte sich nicht darauf verlassen. [PICKY] Das Beispiel ist nicht das beste, da eine Summenoperation ohnehin trivial ist [/PICKY]

Ich würde sagen, deine erste Lösung ist besser, aber noch besser wäre es, die Notwendigkeit der Berechnung vollständig zu entfernen. In den meisten Fällen, wenn eine berechnete Spalte verwendet wird, ist es einfacher, die Berechnung in der Anwendung zu codieren, die das Ergebnis erhält, d.h. wenn dies von php aus aufgerufen wird, lass php statt mysql die Gesamtkilos berechnen. Es handelt sich um eine einmalige Berechnung basierend auf einem einzelnen Rückgabewert und es spielt keine Rolle, ob mySQL es optimiert oder nicht. Wie ich bereits sagte, ist die Summenfunktion günstig, daher ist es für dieses spezielle Beispiel nicht relevant, aber wenn die Operation etwas teurer wäre, würde es eine Rolle spielen und als allgemeine Regel sollten wir nicht von der Trivialität der Operation ausgehen.

Wenn die externe Sprache ein Problem darstellt, wäre eine andere Möglichkeit die Erstellung einer Zwischentabelle und das Aktualisieren dieser Tabelle mit dem Ergebnis. In diesem Fall (eine einzelne Zeile) macht der Overhead dies weniger wünschenswert, aber wenn es viele Zeilen in der Ergebnistabelle wären (wie bei einem Group By) oder um eine allgemeine Richtlinie zu erstellen, wird der Overhead zu einem unwichtigen Punkt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X