Ilja: Performanter SQL

Beitrag lesen

moin,

wenig zeit im moment, deswegen erst eine spätere antwort.

Joins sind böse?????

ja, das ist ein guter grundsatz, nach dem man sich richten sollte. das problem an joins ist die gefahr der vervielfältigung der datensätze in der ergebnismenge, so dass du wie in deinem fall mit DISTINCT arbeiten musst, was performance kostet, um das wieder "gerade zu biegen". du wählst quasi erst die datensätze in der selektionn aus, um sie später wieder zu verwerfen.

natürlich kann man nicht immer auf joins verzichten, zum beispiel weil man genau diese vervielfältigung haben will oder aus anderen gründen. oftmals aber kommt diese vervielfältigung ganz unbewußt zustande, weil jemand noch eine weitere spalte aus einer anderen tabelle in der projektion (ausgabe) anzeigen will und deswegen eine weitere tabelle joint. und schon ist es geschehen, die anzahl der datensätze stimmt nicht mehr.

das prinzip ist, nicht wahllos joinen, sondern erst mal muss die anzahl der datensätze über die selektion stimmen. dann erst sollte man sich gedanken über die projektion machen und nicht umgekehrt.

Wie greifst du dann auf 2 Tabellen gleichzeitig zu?

joins sind nicht der einzige weg, tabellen miteinander zu verknüpfen. unterabfragen haben zwar einen schlechten ruf, aber das ganz zu unrecht. sie sollten das bevorzugte mittel sein.

Performanceverlust? Alle ids haben automatisch einen Index.

auch die unterabfragen werden den index nutzen, aber sie brauchen nicht noch zusätzlich über einen DISTINCT die doppelten datensätze raus filtern und vorher die Datensätze durch das GROUP BY zu sortieren.

Bei dem select kann man auch eh einfach eine group by Anweisung hinzufügen.

viele wege führen nach rom, und auch wenn das gleiche ergebnis raus kommt, so sind nicht alle wege gut. GROUP kostet, genauso wie DISTINCT gibt es solche funktionalitäten nicht umsonst.

Zeig mal bitte deinen Lösungsvorschlag?

du hast dich bei deinem GROUP BY offenbar verschrieben, willst sicherlich nicht zweimal auf die FRIENDS tabelle joinen, sondern das andere mal auf die artikel.

SELECT b.*,
       (SELECT COUNT(*) FROM FRIENDS f WHERE b.uid = f.uid) Freunde,
       (SELECT COUNT(*) FROM ARTIKEL a WHERE b.uid = a.uid) Artikel
FROM Benutzer b
;

Das ist alles, was du brauchst, sieht doch schnuckelig aus....

Ilja