23rd Jun 2022 5 Leseminuten Konvertierung von Unterabfragen in Joins Ignacio L. Bisso JOIN Unterabfrage Inhaltsverzeichnis Wann sollte ich SQL-Subqueries verwenden? Die Daten Beispiel: Ersetzen einer Subquery durch einen JOIN Beispiel: Wenn Unterabfragen die einzige Möglichkeit sind Beispiel: Wenn JOINs und Unterabfragen gleich effizient sind Probieren Sie es selbst aus! Nicht alle Abfragen sind gleich, insbesondere in Bezug auf die Leistung. In diesem Artikel sehen wir uns an, wie Sie SQL-Subqueries in Joins umwandeln können, um die Effizienz zu verbessern. Wann sollte ich SQL-Subqueries verwenden? Gute Frage! Leider gibt es darauf keine konkrete Antwort. SQL-Anfänger neigen dazu, Unterabfragen zu oft zu verwenden. Sobald sie herausgefunden haben, dass die SQL-Konstruktion in einer bestimmten Situation funktioniert, versuchen sie in der Regel, diesen Ansatz auch auf andere Situationen anzuwenden. Das ist ganz natürlich. In einigen Fällen kann eine Subquery jedoch durch ein effizienteres JOIN ersetzt werden. Wenn Sie eine Subquery vermeiden und durch eine JOIN-Klausel ersetzen können, sollten Sie dies ohne zu zögern tun. Aber natürlich gibt es Fälle, in denen die Verwendung einer Subquery die einzige Möglichkeit ist, eine Datenfrage zu lösen. In diesem Artikel zeige ich Beispiele für beide Fälle: wann eine Subquery ein Muss ist und wann eine Subquery vermieden und durch einen JOIN ersetzt werden sollte. Die Daten Bevor wir zu den Beispielen kommen, wollen wir uns kurz die Beispieldatenbank ansehen, die wir verwenden werden. Die Datenbank enthält zwei Tabellen, die die Produktionsstatistiken einer fiktiven Apfelfirma namens EverRed darstellen. Das Unternehmen hat drei Farmen. Die erste Tabelle ist current_year_productiondie Informationen über die Anzahl der im laufenden Jahr von den einzelnen Betrieben produzierten Äpfel sowie über die Fläche und die Anzahl der Bäume in jedem Betrieb enthält. Die zweite Tabelle, production_historyspeichert Informationen über die vergangene Produktion der einzelnen Betriebe. Nachstehend finden Sie einige Beispieldaten aus diesen beiden Tabellen. current_year_production farm_idarea_m2farm_namenumber_of_treesproduction_in_kg 10010000The Paradise2404400 10115000Evergreen3006200 10220000Red Delicious5809300 production_history farm_idyearproduction_in_kgprice_ton 100201741001200 101201758001200 102201794001200 100201639001300 101201664001300 102201691001300 Beispiel: Ersetzen einer Subquery durch einen JOIN Angenommen, Sie sind ein SQL-Datenanalyst, der bei EverRed arbeitet. Der Eigentümer des Unternehmens möchte, dass Sie die Namen der Farmen ermitteln, in denen das Unternehmen im aktuellen Jahr mehr Äpfel produziert als im Vorjahr (2017). Lösung mit einer Subquery: SELECT farm_name, FROM current_year_production CYP WHERE production_in_kg > ( SELECT production_in_kg FROM production_history PH WHERE PH.farm_id = CYP.farm_id AND year = 2017 ) Lösung unter Verwendung einer JOIN-Klausel: SELECT farm_name, FROM current_year_production CYP JOIN production_history PH ON PH.farm_id = CYP.farm_id WHERE PH.year = 2017 AND CYP.production_in_kg > PH.production_in_kg Der Unterschied zwischen diesen beiden Ansätzen liegt in der Leistung. Während die JOIN-Klausel im zweiten Beispiel nur einmal ausgeführt werden muss, wird die Unterabfrage im ersten Beispiel einmal pro Betrieb ausgeführt. In diesem Fall haben wir nur drei Farmen, so dass der Unterschied vernachlässigbar ist. Aber was wäre, wenn Sie für ein größeres Unternehmen mit 10.000 globalen Farmen arbeiten würden? Dann müsste die Subquery 10.000 Mal ausgeführt werden. Es ist klar, dass eine Subquery für unsere Zwecke ineffizient ist. In einer Testdatenbank mit nur wenigen Farmen werden beide Abfragen mit einer akzeptablen Antwortzeit ausgeführt. Wenn wir jedoch zu einer produktiven Datenbank übergehen (wo das Datenvolumen in der Regel viel höher ist), wird die Antwortzeit des Subquery-Ansatzes deutlich ansteigen, während die Antwortzeit des JOIN-Ansatzes stabil bleibt. Das Ergebnis der beiden vorherigen gleichwertigen Abfragen ist: farm_name The Paradise Evergreen Beispiel: Wenn Unterabfragen die einzige Möglichkeit sind Nehmen wir nun an, der Eigentümer des Unternehmens bittet Sie, nachdem er die Ergebnisse der vorherigen Abfrage gelesen hat, um die Namen der Betriebe, die in diesem Jahr mehr Äpfel pro Quadratmeter produzieren als der historische Durchschnitt. Das klingt kompliziert, ist aber einfacher als es scheint. Lösung mit einer Unterabfrage: SELECT farm_name, production_in_kg / area AS "production_per_meter" FROM Current_year_production WHERE production_in_kg / area > ( SELECT AVG(PH.production_in_kg / CYP.area) FROM production_history PH JOIN Current_year_production CYP ON PH.farm_id = CYP.farm_id ) Wir können diese Unterabfrage nicht durch einen JOIN ersetzen, da wir keine Tabelle mit dem zuvor berechneten Durchschnitt haben. Mit anderen Worten, wir müssen zuerst den historischen Durchschnitt berechnen. Und dazu brauchen wir eine GROUP BY, die die für einen JOIN erforderliche Eins-zu-Eins-Beziehung aufheben kann. Ein weiterer wichtiger Punkt ist, dass die Metrik "Äpfel pro Quadratmeter" mit dem folgenden Ausdruck ermittelt wird: production_in_kg / area Wir haben die Metrik "Äpfel pro Quadratmeter" verwendet, weil wir eine Möglichkeit brauchen, um die Produktivität der verschiedenen Betriebe zu vergleichen und sie in eine Rangfolge zu bringen. Die gesamte "Produktion_in_kg" eines Betriebs ist kein vergleichbarer Wert, da es wahrscheinlich ist, dass der größte Betrieb beispielsweise eine bessere production_in_kg hat. Daher teilen wir die "Produktion_in_kg" durch die Fläche jedes Betriebs, um die Werte zu standardisieren und eine vergleichbare Kennzahl zu schaffen. Wir stellen fest, dass der historische Durchschnitt der Produktion pro Quadratmeter 0,42 beträgt. Das Ergebnis der vorangegangenen Abfrage lautet also: farm_nameproduction_per_meter The Paradise0.44 Red Delicious0.47 Beispiel: Wenn JOINs und Unterabfragen gleich effizient sind Als letzte Datenfrage wollen wir versuchen, die Jahre zu ermitteln, in denen das Unternehmen weniger Äpfel produziert hat als im aktuellen Jahr. Wir können diese Abfrage mit zwei verschiedenen Ansätzen schreiben. Lösung mit einer Unterabfrage: SELECT year, sum(production_in_kg) FROM production_history PH GROUP BY year HAVING sum(production_in_kg) < ( SELECT sum(production_in_kg) FROM current_year_production ) Lösung unter Verwendung einer JOIN-Klausel: SELECT year, sum(PH.production_in_kg) FROM production_history PH JOIN current_year_production CYP ON PH.farm_id = CYP.farm_id GROUP BY year HAVING sum(PH.production_in_kg) < sum(CYP.production_in_kg) Sie sehen, dass diese beiden Abfragen sehr ähnlich sind; der Hauptunterschied liegt in der JOIN-Klausel und der Unterabfrage. In diesem Fall sind beide Abfragen gleich effizient - die Unterabfrage wird nur einmal in der HAVING-Klausel ausgeführt, so dass es keine Leistungsprobleme gibt. Probieren Sie es selbst aus! Abschließend ist es wichtig, darauf hinzuweisen, dass Unterabfragen und JOINs für einen SQL-Entwickler sehr wichtige Ressourcen sind. Wir haben Beispiele gesehen, in denen wir eine Subquery durch einen JOIN ersetzen können, und Beispiele, in denen dies nicht möglich ist. Und manchmal sind Unterabfragen und JOINs gleichermaßen effizient. Aber woher wissen Sie, wann Sie eine Unterabfrage und wann einen JOIN verwenden sollten? Um ehrlich zu sein, können Sie Ihre Intuition nur entwickeln, indem Sie regelmäßig SQL-Aufgaben lösen. Wenn Sie Ihre SQL-Kenntnisse auffrischen möchten, bietet unser SQL-Übungssatz bietet 88 Übungsaufgaben für eine umfassende Überprüfung. Bleiben Sie dran für weitere Artikel! Tags: JOIN Unterabfrage