[MySQL] Geschwindigkeit Lesbarkeit Effizienz

chmee

verstaubtes inventar
Premium-User
Für das derzeitige Projekt sitze ich also nun "mal wieder" an MySQL. Ich würde natürlich alle Queries soweit optimieren, dass ich das nicht später nochmal machen muss. Beim Querlesen auf anderen Seiten kommen dann solche Gedanken, wie man die Query ressourcenschonend schreibt.

Geschwindigkeit sehe ich als primär an.

Ist Geschwindigkeit auch mit Effizienz / niedriger Last gleichzusetzen ?

Nun habe ich zB gelesen, dass
Subselects schneller sind als Joins - (wenn man denn joins immer durch subselects ersetzen kann).
Link

Gibt es weitere solcher Hints, bzw. gibt es Fallstricke in Bezug auf die Versionsnummer?

In meinem Fall habe ich eine Query, die sich über 8 Tabellen erstreckt - Normalform sei Dank.
Code:
SELECT *
 
FROM YP_Poster,YP_Poster_Data,YP_ImgFiles,YP_Poster_Desc,YP_Formate,YP_fArt,YP_fSize,YP_fDesc 

WHERE YP_Poster.User_ID='".$_SESSION[User_ID]."'
 
AND YP_Poster_Desc.Poster_ID=YP_Poster.Poster_ID 
AND YP_Poster_Data.Poster_Data=YP_Poster.Poster_Data 
AND YP_ImgFiles.File_ID=YP_Poster_Data.File_ID 
AND YP_Poster_Data.Format_ID=YP_Formate.Format_ID
AND YP_Formate.fArt_ID=YP_fArt.fArt_ID
AND YP_Formate.fSize_ID=YP_fSize.fSize_ID
AND YP_fSize.fDesc_ID=YP_fDesc.fDesc_ID

Um also alle Poster eines Users -samt der Daten zum Poster- zu erhalten, wird so eine Query in dieser Form schon recht lang -sicherlich auch langsamer als eine andere Abfrageform.Wie würde man so eine Query effizienter notieren?

mfg chmee
 
Hallo chmee,

SubSelects sind nur sinnvoll, wenn man dadurch die Datenmenge gegenüber einem Join reduziert.
Also nur wenn es eine Bedingung gibt, die den SuSelect dann einschränkt.

So könnte es dann aussehen:
Code:
SELECT *
FROM (SELECT * FROM YP_Poster WHERE YP_Poster.User_ID='".$_SESSION[User_ID]."') as YP_Poster
INNER JOIN YP_Poster_Data ON YP_Poster_Data.Poster_Data=YP_Poster.Poster_Data
INNER JOIN YP_ImgFiles ON YP_ImgFiles.File_ID=YP_Poster_Data.File_ID
INNER JOIN YP_Poster_Desc ON YP_Poster_Desc.Poster_ID=YP_Poster.Poster_ID 
INNER JOIN YP_Formate ON YP_Poster_Data.Format_ID=YP_Formate.Format_ID
INNER JOIN YP_fArt ON YP_Formate.fArt_ID=YP_fArt.fArt_ID
INNER JOIN YP_fSize ON YP_Formate.fSize_ID=YP_fSize.fSize_ID
INNER JOIN YP_fDesc ON YP_fSize.fDesc_ID=YP_fDesc.fDesc_ID
Ausserdem ist die schreibweise mit explizieten Joins viel übersichtlicher
und "SELECT *" bei so vielen Tabellen ist auch nicht gerade übersichtlich.
Daher besser im Select nur die Felder ausgeben lassen, die man wirklich benötigt.
 
Moin chmee,

wie auch schon in dem von Dir zitierten Link anklingt:
Eine pauschale Behauptung "SubSelects sind effizienter als explizite Joins (oder umgekehrt)" ist ein ziemlich schmales Brett.

Und relativ schnell ad absurdum zu führen.
Selbst in Deinem geposteten Beispiel, zu dem wir ja nur unsere Phantasie bezüglich der Datenvolumen in den Tabellen bemühen können, würde ich mir zum Beispiel rauspicken:

Code:
...
AND YP_ImgFiles.File_ID=YP_Poster_Data.File_ID 
...
AND YP_Formate.fArt_ID=YP_fArt.fArt_ID

Bei der ersten Relation unterstelle ich, dass, wenn in YP_ImgFiles insgesamt 10000 Datensätze sind, auch in der YP_Poster_Data-Tabelle der passende DS aus in etwa der gleichen Anzahl DS rausgeflöht werden muss.
Ansatz: Inner-Join, da im Datenmodell vermutlich 1:1-Relation (oder 0/1:1?). und das ganze via EXPLAIN anschauen.

Die zweite Relation dagegen, wo vielleicht eine von fünf YP_fArt.fArt_IDs aus einem Kennzeichen-Tabellchen geholt werden muss... da könnte ein Subselect flotter sein.

Aber anyway - Du hast unterschiedliche Parent-Child-Beziehungen (1:1; 1:n; n:m..) und entsprechend auch sehr ungleichgewichtige Datensatzanzahlverhältnisse.

Wenn Performanz für deine Appz/Deine Kunden ein wichtiges Gütekriterium ist, dann heißt es ohnehin optimieren statt pauschalieren.
Also ran an EXPLAINs und Zugriffspfade und das Tuning.

Grüße
Biber
 
Zuletzt bearbeitet:
Erstmal Danke Euch beiden, interessant zu lesen und das erhellt das Ganze ein bisschen..

Zur Beispielquery :
Das ImgFile ist das File zum Poster, Jenes ImgFile kann aber auch für ein weiteres Poster in einer anderen Größe genutzt werden, ergo 1:n.

Ich schau mir mal EXPLAIN an und schreib mir mal verschiedene Queries, um zu schauen, wie die Zugriffe laufen. Danke.

mfg chmee

p.s.: Kann man denn eine Faustregel nennen ? Große 1:n oder 1:1 mit JOIN, kleine 1:1 oder 1:n mit Subselect oder Ähnlich?
 
Zurück