Rolf b: zuviele Treffer in einer MYSQ Abfrage

Beitrag lesen

Nein, da verwechselst Du Theorie und Praxis. Jürgens Query ist semantisch ein JOIN.

Natürlich ist es in der Coddschen Theorie so, dass eine Query mit zwei Tabellen im FROM zunächst mal zum kartesischen Produkt aufgespannt wird, an Hand der WHERE Angaben selektiert und schließlich basierend auf der SELECT-Liste projiziert wird.

Der DB Server weiß aber genauso gut wie wir, dass dieses Vorgehen im Allgemeinen blödsinnig ist. Queries laufen durch einen Optimizer, der basierend auf Statistiken und Schmierfett (=Indexe) einen hoffentlich optimalen Zugriffspfad findet (den man sich per EXPLAIN-Befehl auf mehr oder weniger verständliche Art darstellen lassen kann). Wie man einen solchen Optimizer baut, ist teils durch die Relationale Algebra vorgegeben, teils aber auch Geschäftsgeheimnis der jeweiligen Anbieter von DB-Servern.

Ob ich nun

SELECT a.dings, b.bums FROM tab1 a, tab2 b WHERE a.id = b.ref_id

schreibe oder

SELECT a.dings, b.bums FROM tab1 a JOIN tab2 b ON a.id = b.ref_id

das ist dem Optimizier komplett egal, es ist semantisch beide Male ein INNER JOIN und wird normalerweise in eine "nested loop" übersetzt. Wer in dieser Schleife innen und wer außen ist, entscheidet sich an Hand von Table-Größen und Vorhandensein von Indexen zur Laufzeit.

Nested Loop heißt, als Pseudocode:

foreach (satz in tab1) {
   foreach (satz in tab2 wo b.ref_id = a.id)
      (a.dings, b.bums) in Ausgaberelation schreiben
}

Ob "satz in tab1" per einfachem Table-Scan, per Index-sortiertem Table-Scan, oder per Index-Scan ermittelt wird, ist mal wieder eine Optimizer entscheidung.

Ob "satz in tab2 wo b.ref_id = a.id" ein Table-Scan, ein Direktzugriff per Index oder ein reiner Index-Zugriff ist, ebenfalls.

Und selbst wenn der Optimizer sich für einen Table-Scan entscheidet, kann das immer noch die fixeste Lösung sein, wenn die Tables so klein sind, dass der Server sie im RAM halten kann. Von Besonderheiten wie spaltenorientierter Speicherung mal ganz abgesehen...

Reine Index-Zugriffe finden dann statt, wenn die Datenfelder, die in die Ausgaberelation gehören, Teil des Index sind, über den gelesen wird. Dann greift er auf die eigentliche Table gar nicht mehr zu.

Rolf