JOIN-Verständnisfrage
Kuno
- datenbank
0 Horst0 Vinzenz Mai0 Kuno
0 Vinzenz Mai0 Kuno0 Vinzenz Mai0 Rouven
Datenbank: mySQL
Habe zwei Tabellen: sessions (100 Datensätze), users (40.000 Datensätze)
Die Tabellen sind in etwa das was man anhand des Namens vermuten würde.
Ich möchte nun alle user anzeigen, die online sind.
Dazu habe ich zwei Varianten:
Wichtig: In wirklichkeit wird natürlich auf die integeren Primärschlüssel zugegriffen. Ich verwende aber zum einfacheren Verständnis im Beispiel "name"-Spalten.
Variante 1:
SELECT a.name FROM users a INNER JOIN sessions b ON a.name = b.name
Variante 2:
SELECT b.name FROM sessions b INNER JOIN users b ON b.name = a.name
Nun meine Frage:
in "users" befinden sich viele Tausende Einträge. In sessions nur wenige Hundert.
Ich tendiere zu Variante 1.
Ich kann aber beim besten Willen keinen Performancevergleich machen da mir die mysql-Konsole trotz riesiger Test-Datenbanken das Ergebnis in 0.00 sec ausliefert.
welche Variante ist vorzuziehen?
Hallo,
welche Variante ist vorzuziehen?
Keine von Beiden, Du suchst einen "Outer Join" und zwar einen "Left".
Viele Grüße,
Horst Haselhuhn
Hallo Horst,
welche Variante ist vorzuziehen?
Keine von Beiden, Du suchst einen "Outer Join" und zwar einen "Left".
wieso denn das? Kuno sucht doch ausschließlich die Benutzer, für die derzeit
eine Session existiert. Da sollte der INNER JOIN angemessen sein.
Freundliche Grüße
Vinzenz
Hallo Kuno,
SELECT a.name FROM users a INNER JOIN sessions b ON a.name = b.name
SELECT b.name FROM sessions b INNER JOIN users b ON b.name = a.name
Ich tendiere zu Variante 1.
Ich kann aber beim besten Willen keinen Performancevergleich machen da mir die mysql-Konsole trotz riesiger Test-Datenbanken das Ergebnis in 0.00 sec ausliefert.
Befrage EXPLAIN
Freundliche Grüße
Vinzenz
Das hatte ich mir auch schon so überlegt, aber wenn dort die Werte bei beiden Statements identisch sind was ja der Fall ist, ist das dann auch performancetechnisch wirklich dasselbe?
Weil meine Verstand sagt mir folgendes:
Variante 1:
SELECT a.name FROM users a INNER JOIN sessions b ON a.name = b.name
Verstand: mySQL geht die gesamte users-Tabelle durch und guckt dann, welche auch in sessions vorkommen.
Variante 2:
SELECT b.name FROM sessions b INNER JOIN users b ON b.name = a.name
Verstand: mySQL guckt ZUERST in die kleinere Tabelle um dann danach erst gezielt auf users zuzugreifen.
Mein Fazit: Bei Variante 2 muss ja nicht die komplette users durchlaufen werden.
Hallo Kuno,
Das hatte ich mir auch schon so überlegt, aber wenn dort die Werte bei beiden Statements identisch sind was ja der Fall ist, ist das dann auch performancetechnisch wirklich dasselbe?
Du solltest Dir wirklich das Kapitel Optimierung durchlesen :-)
Warum könnten die Werte exakt gleich sein? Eine mögliche Antwort ist, dass
der Optimierer von MySQL zuschlägt und von den beiden Varianten die nimmt,
die er effizienter abarbeiten kann.
SELECT a.name FROM users a INNER JOIN sessions b ON a.name = b.name
SELECT b.name FROM sessions b INNER JOIN users b ON b.name = a.name
Du solltest daher statt der oben angeführten Statements eher
SELECT a.name FROM users a STRAIGHT_JOIN sessions b ON a.name = b.name
SELECT b.name FROM sessions b STRAIGHT_JOIN users b ON b.name = a.name
um die Reihenfolge der Tabellen vor dem Optimierer zu "schützen".
Siehe dazu neben dem bereits verlinkten Handbuchabschnitt den Abschnitt JOIN.
Freundliche Grüße
Vinzenz
Hello,
Mein Fazit: Bei Variante 2 muss ja nicht die komplette users durchlaufen werden.
möglich, aber du machst den Fehler zu glauben, dass die Datenbank dein Statement auch wirklich so ausführt wie du es abschickst. Das stimmt nicht ohne weiteres, dazwischen liegen noch ein paar Instanzen (hatte mal eine schöne Grafik, find ich leider nicht mehr), die u.a. für die Optimierung des Statements zuständig sind, z.B. kann es sinnvoll sein umzusortieren, damit Indizes genutzt werden können.
MfG
Rouven