moin,
Ok, Wartbarkeit ist tatsächlich ein Grund, wobei so ein JOIN ja oft einfach benutzt wird um eine _simple_ Verknüpfung darzustellen (z.B. von userID auf Namen schließen).
die wartbarkeit ist ein aspekt, die performance ein anderer, aber beides ist nicht der hauptgrund, warum joins "böse" sind. es geht darum, eine gute methode anzuwenden, wie man ein sql statement aufbaut. das ist eine grundsätzliche methodik, die man sich aneignen sollte, weil man nach meiner erfahrung damit wesentlich weniger fehler macht. und genau bei dem weg, den du hier anführst, kommen die besagten probleme, indem man schnell noch mal ein attribut in der projektion mit anzeigen will. für mich ist der richtige weg aber genau entgegen gesetzt, sprich man läßt die projektion erst einmal komplett aussen vor, wichtig ist zuvor die richtige selektion, sprich die richtige datenbasis in der ergebnismenge zu finden. hilfreich dafür wäre erst mal nur die selektion zu erstellen und in der projektion ein COUNT(*) ausgeben zu lassen. und erst wenn die selektion steht, dann sollte man sich gedanken über die projektion machen. und selbst dann bevorzuge ich unterabfragen in der projektion als joins.
natürlich machen auch joins an der richtigen stelle sinn, sehr viel sogar, zum beispiel wenn ich eben genau diese mögliche vervielfachung der datensätze durch jons brauche, als genau das die gewünchte datenbasis der ergebnistabelle darstellt. und natürlich kann ich auch mal schnell joins für eine ad hoc abfrage bilden, wenn die anzahl der datensätze nicht relevant ist, sondern ich mir nur schnell einen überblick verschaffen will. oder aber mir sind die beziehungen der tabellen untereinander bewußt. das ist dann aber ein ganz expliziter und bewußter vorgang, wo ich mir bei jedem join (und wirklich jedem) gedanken über die art der beziehung mache und wie es sich auf die ergebnistabelle auswirkt.
JOIN userTbl ON userTbl.id = foo.userId
Jeder mit SQL-Grundkentnissen sollte die Verknüpfung erkennen und verstehen können - denke ich.
lesbarkeit bedeutet nicht, dass man weiß, wie ein JOIN gebildet wird, sondern wie schnell ich eine abfrage verstehen kann, wenn ich sie zum beispiel zum ersten mal lese oder seit langer zeit mal wieder. natürlich kann man oftmals einen join durch geschickte bedinungen auch so aufbauen, dass man zum gleichen ergebnis kommen würde, als wenn man unterabfragen benutzt. aber in aller regel ließt sich der sinn hinter der abfrage schwieriger, der fachliche sinn, nicht das verständnis wie ein JOIN aufgebaut ist. wenn ich nur eine tabelle in der FROM klausel habe und alles weitere mit unerabfragen abfackel, dann weiß ich auf den ersten blick viel schneller, um welche daten es geht. habe ich mehrere tabellen dort durch JOINS im verbund, dann muss ich mir erst mal gedanken machen, um welche entität jetzt eine aussage gemacht werden soll oder ist es wichtig, dass es um zwei entitäten geht, ist der join nur vorhanden, um in die projektion zugehen oder die selektion weiter einzugrenzen, etc.
Und was sagt deine Erfahrung? Ich würde mal tippen gerade bei komplexen und vielen JOINs kann ein gutes DBMS optimieren, aber ich muss gestehen ich habe noch nie nachgemessen.
performace ist so eine sache bei datenbanken. es gibt ein grundsatz, es kommt oftmals anders als man denkt. natürlich zählen auch die erfahrungswerte dabei und es kommt oftmals auch hin, aber wenn wirklich tuning bedarf besteht, dann muss man eben messen und nochmals messen, wie Vinzenz schon richtigerweise erwähnte. aber aus meiner erfahrung heraus, sind die unterabfragen besser, als joins, erst recht wenn dann noch OUTER JOINS ins spiel kommen.
also noch mal zusammengefasst, warum ich zu dem motto komme, dass JOINS "böse" sind.
- fehleranfälliger schon bei der erstellung (hauptgrund)
- nicht unterstützend in der fehlererkennung, wenn die abfrage läuft (unterabfragen knallen in der projektion, wenn sie mehr als ein datensatz zurück liefern)
- schlechter lesbar (schließt wartbarkeit mit ein)
- meiner erfahrung nach im schnitt schlechtere performance
und alleine der erste grund ist schon gewichtig genug.
Ilja