Seite 1 von 1
SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Montag 26. März 2018, 14:33
von Zoja
Situation:
Ich habe eine table Projekte. Projekte können eine bestimmte Anzahl Videos besitzen. Um die Anzahl zu erfahren könnte ich die Projekte mit der videos table joinen und einen count() ausführen, dann wüsste ich wieviele Videos ein Projekt besitzt.
Ich könnte aber auch bei Projekte eine neue column anlegen "anzahl videos" und diese += 1 rechnen sobald ein neues video dazukommt. Ich spare mir den join und count, habe aber eine column mehr, die ich sonst hätte ausrechnen können.
Welche dieser beiden Ansätze ist besser? Was sollte man beachten?
Danke
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Montag 26. März 2018, 14:54
von Sirius3
@zoja: besser ist es immer, etwas zu berechnen, statt es händisch pflegen zu müssen.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Montag 26. März 2018, 14:57
von Zoja
Sirius3 hat geschrieben:@zoja: besser ist es immer, etwas zu berechnen, statt es händisch pflegen zu müssen.
Aber wie sieht es mit der Performance aus? Jedesmal wenn man die Projektseite aufrufen würde, würde das System einen join machen und count ausführen, um zu berechnen wieviele Videos zum Projekt gehören?
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Montag 26. März 2018, 15:15
von __deets__
Hast du ein Performance Problem, oder antizipierst du eines? Wenn letzteres - warte ab.
Eine SQL-Abfrage verlaesst deinen Prozess via Netzwerk, landet in einem anderen Prozess, wird dort auseinander gepult, durch den Execution-Planer der DB-Engine geschoben, und erst dann wird da ueber irgendwelchen Tabellen gearbeitet. Und ggf. befinden die sich im Speicher, so das das recht flott geht. Und dann wieder zurueck durch die ganzen Schichten.
Das nun ausgerechnet dieser join da der Strohalm ist, der den Kamelruecken zerbricht - das ist unwahrscheinlich.
Alles in allem ist es eine schlechte Vorgehensweise, Performance-Probleme vorhersagen zu wollen. Und wenn kann man das auch nur anhand von klar definierten Kriterien. Denn schneller geht immer, nur wird irgendwann der Aufwand dafuer nicht mehr rechtfertigbar.
Hast du zB ueberhaupt fest definierte Ziele fuer die Laufzeit von Anfragen? Und wenn du die hast, muessen es *garantiert* weniger als x Millisekunden sein, oder duerfen zB 5% aller Anfragen darueber liegen?
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Montag 26. März 2018, 15:34
von Zoja
__deets__ hat geschrieben:Hast du ein Performance Problem, oder antizipierst du eines? Wenn letzteres - warte ab.
Eine SQL-Abfrage verlaesst deinen Prozess via Netzwerk, landet in einem anderen Prozess, wird dort auseinander gepult, durch den Execution-Planer der DB-Engine geschoben, und erst dann wird da ueber irgendwelchen Tabellen gearbeitet. Und ggf. befinden die sich im Speicher, so das das recht flott geht. Und dann wieder zurueck durch die ganzen Schichten.
Das nun ausgerechnet dieser join da der Strohalm ist, der den Kamelruecken zerbricht - das ist unwahrscheinlich.
Alles in allem ist es eine schlechte Vorgehensweise, Performance-Probleme vorhersagen zu wollen. Und wenn kann man das auch nur anhand von klar definierten Kriterien. Denn schneller geht immer, nur wird irgendwann der Aufwand dafuer nicht mehr rechtfertigbar.
Hast du zB ueberhaupt fest definierte Ziele fuer die Laufzeit von Anfragen? Und wenn du die hast, muessen es *garantiert* weniger als x Millisekunden sein, oder duerfen zB 5% aller Anfragen darueber liegen?
Nein, das ist eher eine allgemeine Frage, das schwirt schon länger in meinem Kopf rum. Also ist es abhängig von der Situation.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Montag 26. März 2018, 17:34
von __deets__
Bei Performance immer. Es gibt zwei grundlegende Regeln:
- premature optimisation is the root of all evil. Optimiere nicht fuer ein Problem, von dem du noch nicht mal weisst, das du es hast. Natuerlich muss man sich deswegen nicht stulle bloed anstellen, aber wie ich gerade auch ganz akut auf arbeit merke: woher ploetzlich Performance-Probleme auftauchen weiss man gar nicht, und sollte dann auf sie reagieren, wenn sie wirklich auftreten.
- man normalisiert Datenbanken moeglichst weitgehend. Der Wikipedia-Eintrag dazu erklaert das ganz gut:
https://de.wikipedia.org/wiki/Normalisi ... Datenbank)
Dein Vorgehen wuerde die 3. Normalform verletzen, denn die Anzahl der Videos laesst sich ja auch aus der Untertabelle bestimmen.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Montag 26. März 2018, 22:12
von DasIch
Grundsätzlich solltest du bei deiner primären Datenbank konservative Entscheidungen fällen, falls du die Daten einmal vermurkst hast ist es schwierig da wieder zu korrigieren. Dementsprechend würde ich von so einer Optimierung abraten selbst wenn du ein Performance Problem hättest.
Eine bessere Alternative wäre z.b. das Ergebnis des Queries in einem Cache zu halten. Gerade sowas lässt sich sehr leicht cachen, weil man solche Statistiken einfach periodisch im Hintergrund aktualisieren kann.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Dienstag 27. März 2018, 01:05
von IHack
Wenn du für echte DBs schreibst, kannst du getrost davon ausgehen, dass die schneller sind, als du deine zusätzliche Videospalte der Projekte schreiben kannst.
Lass es.
Es widerspricht dem hehren Ziel der Atomisierung von DBs.
(Keine Information mehr als einmal. Egal ob implizit, oder explizit)
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Dienstag 27. März 2018, 03:46
von DasIch
IHack hat geschrieben:Wenn du für echte DBs schreibst, kannst du getrost davon ausgehen, dass die schneller sind, als du deine zusätzliche Videospalte der Projekte schreiben kannst.
Das ist offensichtlich falsch. Mit einer separaten Spalte für die Anzahl hat man bessere algorithmische Komplexität und auch in der Praxis wird es definitiv schneller sein, sobald man soviele Daten hat dass das zählen einen signifikanten Zeitraum beansprucht.
Normalisierung ist auch nicht immer ideal und es gibt viele Situationen wo es Sinn macht oder es sogar empfehlenswert ist zu denormalisieren. Datenbanken bieten mit (materialized) views teilweise auch Features um dies leicht zu ermöglichen.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Dienstag 27. März 2018, 09:51
von Sirius3
@DasIch: mit dem passenden Index ist das Zählen eine O(1)-Operation.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Dienstag 27. März 2018, 10:09
von __deets__
@Sirius3 das wuerde mich wundern. Der Index sollte doch normalerweise in Form eines B-Tree oder aehnlichem daherkommen. Auch der traversiert sich doch nicht in O(1)-Zeit?
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Dienstag 27. März 2018, 13:11
von snafu
Zoja hat geschrieben:Ich könnte aber auch bei Projekte eine neue column anlegen "anzahl videos" und diese += 1 rechnen sobald ein neues video dazukommt. Ich spare mir den join und count, habe aber eine column mehr, die ich sonst hätte ausrechnen können.
Ich würde das berechnen, solange der Zeitaufwand dafür relativ gering ist. Und das ist er oft. Wenn das Ergebnis häufig benötigt wird, dann liegt es wahrscheinlich eh im Cache deines DBMS. Da musst du diese Abeit und das Mehr an Verwaltung nicht zusätzlich machen.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Dienstag 27. März 2018, 14:03
von DasIch
Sirius3 hat geschrieben:@DasIch: mit dem passenden Index ist das Zählen eine O(1)-Operation.
Nur wenn du eine Tabelle mit einer Zeile hast in der der Count steht.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Dienstag 27. März 2018, 14:21
von /me
DasIch hat geschrieben:Nur wenn du eine Tabelle mit einer Zeile hast in der der Count steht.
Es kann aber durchaus sein, dass die DB das intern ohnehin mitführt. Das weiß man allerdings üblicherweise nicht.
Die entscheidende Frage ist: Will man lieber etwas Performanceverlust beim Ermitteln der Anzahl oder will man bei jedem INSERT und DELETE händisch einen Counter anpassen (Race-Conditions nicht vergessen!)? Das hängt im Endeffekt vom Anwendungsfall ab und dabei insbesondere von der Frage, wie häufig die jeweiligen Operationen erwartungsgemäß durchgeführt werden.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Dienstag 27. März 2018, 19:25
von DasIch
snafu hat geschrieben:Wenn das Ergebnis häufig benötigt wird, dann liegt es wahrscheinlich eh im Cache deines DBMS.
Postgres hat keine Cache für Ergebnisse. MySQL hat den abgeschafft.
Einen Cache hat man üblicherweise nur für Queries (wegen Parsing Overhead), Tabellen und Indizes (in beiden Fällen wegen Disk I/O).
/me hat geschrieben:Es kann aber durchaus sein, dass die DB das intern ohnehin mitführt. Das weiß man allerdings üblicherweise nicht.
Sowas ist sehr gut dokumentiert, wenn man Performance Probleme hat sollte man dies wissen.
So einen Counter zu aktualisieren lässt sich z.B. über einen Trigger relativ problemlos machen. Relationelle Datenbanken kommen mit Concurrency schon ziemlich gut klar.
Wir reden hier nicht über zwei O(1) Operationen, von denen eine ein bisschen langsamer ist. Selbst wenn man eine Tabelle hat in einer Größenordnung von 100M Zeilen, was noch problemlos in den Arbeitsspeicher passt, kann es durchaus Minuten dauern bis man die Zeilen gezählt hat. Das ist alles andere als "etwas Performanceverlust".
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Mittwoch 28. März 2018, 12:21
von /me
DasIch hat geschrieben:/me hat geschrieben:Es kann aber durchaus sein, dass die DB das intern ohnehin mitführt. Das weiß man allerdings üblicherweise nicht.
Sowas ist sehr gut dokumentiert, wenn man Performance Probleme hat sollte man dies wissen.
Finde das mal bei Oracle heraus. Und das noch über verschiedene Versionen und Patchlevel. Ich verwende Oracle seit Version 6 und habe da schon einige unschöne Überraschungen erlebt. Unter anderem spielt dann auch noch eine Rolle, wie oft man die Statistiken aktualisiert - und das ist nur der dokumentierte Teil.
DasIch hat geschrieben:Wir reden hier nicht über zwei O(1) Operationen, von denen eine ein bisschen langsamer ist. Selbst wenn man eine Tabelle hat in einer Größenordnung von 100M Zeilen, was noch problemlos in den Arbeitsspeicher passt, kann es durchaus Minuten dauern bis man die Zeilen gezählt hat. Das ist alles andere als "etwas Performanceverlust".
Klar, in der Größenordnung wird es unhandlich. Ich habe gerade mal testweise auf einer Oracle 11 einen COUNT auf eine partitionierte Tabelle mit 393.669.171 Einträgen abgesetzt. Der erste Durchlauf dauerte satte 3:10 Minuten, der zweite dann immerhin auch noch 0:35. Das ist für einen interaktiven Zugriff typischerweise inakzeptabel. Auf Tabellen mit nur ein paar 100.000 Zeilen bewege ich mich dafür im Millisekundenbereich. Bei vielen INSERT- und DELETE-Vorgängen werden Trigger allerdings auch irgendwann nicht mehr lustig. Deshalb sage ich ja: es hängt vom Anwendungsfall ab.
Re: SQL join und count VS. column für die Anzahl, was ist effizienter?
Verfasst: Donnerstag 12. April 2018, 14:15
von Zoja
Vielen Dank nochmal an alle, die sich gemeldet haben. Sehr wertvolle Informationen für mich.