[MySQL] JOIN

liquidbeats

Erfahrenes Mitglied
Nabend,

ich stehe momentan vor dem Problem mich mit dem JOIN an sich weiter auseinander zu setzen zu müssen.

Bisher habe ich i.d.R LEFT JOIN benutzt. Vorteil war dieser, das ich auf nix weiter achten musste, ergebnisse waren immer wie gewünscht. Das dies jedoch nicht so Performant gewesen ist, war bis dato egal. Bei 20 Datensätzen macht dies den Kohl auch nicht Fett.

Jetzt habe ich jedoch ein Performance Problem. Die Datenbank beinhaltet, von mir Testweise 5000 eingetragene Datensätze. Um genau zu sein sind es 5284.

Ich habe 3 Tabellen die es gilt in das Statement mit einzubeziehen.
Die Haupttabelle, immobilien
Die Tabelle für Texte, freitexte
und die Tabelle für Bildmaterial, anhaenge

In allen Tabellen findet sich eine ID wieder "immobilien_id", die dafür gedacht ist, sämtliche Datensätze miteinander zu verknüpfen, was auch klappt.

Zum Aufbau möchte ich folgendes sagen.
Primär ist die Tabelle immobilien wichtig, in dieser sind 5200 Datensätze, in der Tabelle freitexte finden sich ebenfalls 5200 wieder, die mit dem Passenden gegenstück in der Tabelle immobilien verknüpft sind (immobilien_id).
Die Tabelle anhaenge hingegen hat nur 17 einträge, wobei dort mehrere einträge ein und dem selben eintrag von immobilien zugeordnet sind.
Eben dem Motto, ein Objekt hat 2 Bilder das andere nur eines und andere wiederum keine Bilder zugeordnet bekommen.

Ziel ist es, alle Datensätze, unabhängig davon ob Passende Daten in der Tabelle anhaenge bereit stehen, zu selektieren und auszugeben. Mit LEFT JOIN klappt das, jedoch ist die Ausführungszeit Katerstrophal, diese beträgt mehrere Minuten.
INNER JOIN scheint mir da Performanter zu sein, Problem ist jedoch dass ich genau 17 Datensätze, eben die anzahl aus der Tabelle anheange bekomme. Wenn ich jetzt DISTINCT und GROUP BY immobilien.immobilien_id nutze verbleiben Logischerweise nur noch 6 Resultierende Datensätze.

Hat jemand einen Vorschlag für mich?
Ein Deutsches tutorial bezüglich MySQL wäre ebenfalls nicht schlecht, wenn jemand eines Empfehlen kann. Ich bin jetzt an dem Punkt angekommen wo ich merke das mein Wissen in diesem bereich ungenügend ist.

Vielen Dank

Grüße
 
Hi,

mehrere Minuten gehen da bestimmt nicht nur für die Abfrage drauf. Ich kann hier zwar gerade nur mit rund 850 Datensätzen aufwarten, aber eine Abfrage mit 2 LEFT JOINS wird mir in 0,01 sec ausgeführt. Außerdem habe ich schon mal eine Abfrage zur Datenreparatur schreiben müssen, die ein correlated Subquery enthielt. Lief über ca. 80000 Datensätze in 5 sec. durch...

Wie verarbeitest Du denn das Ergebnis? Per PHP in einer Schleife?

LG
 
JA verarbeitet wird das mit PHP und ner normalen Schleife, aber nicht alle 500 Datensätze aufeinmal. Sind max. 20, eben pro Seite.

Auch in der Konsole dauert die abfrage derart lange, so dass das Problem nicht bei der Umsetzung innerhalb von PHP zu suchen ist.
 
Gezippt, hmm keine Ahnung, aber nicht sonderlich Groß. Mit Explain habe ich schon gearbeitet, aber um Ehrlich zu sein, ich kapiert nicht was er mir damit sagen will.

Obwohl 2 Datensätze aus der DB dem Suchmuster übereinstimmen, holt er mir 8 raus. Das Problem an sich konnte ich soweit Lokalisieren dass eben die Bilder, wo einem Objekt teilweise mehrere zugewiesen sind als einzellne Einträge rausgeholt werden. Mit Group BY klapt das zwar, aber nunja, ich Denke, den ganzen aufbau wohl überdenken zu müssen.

Den SQL Statement werde ich gleich mal nachreichen, ca 5. Minuten.

Grüße
 
Hier ist der SQL Statement.
PHP:
SELECT  
    s.*,
    s.kaufpreis AS kosten,
    attach.web_server,
    frt.objekttitel,
    frt.lage,
    p.waehrung
FROM    
    search AS s            
LEFT JOIN 
    anhaenge AS attach ON (s.immobilien_id = attach.immobilien_id)
INNER JOIN 
    freitexte AS frt ON (s.immobilien_id = frt.immobilien_id)
INNER JOIN
    preise AS p ON (s.immobilien_id=p.immobilien_id)    
WHERE 
    s.nutzungsart            ='WOHNEN'     AND 
    s.objektart            ='wohnung'     AND 
    s.vermarktungsart        ='KAUF'     AND 
    s.wohnungtyp            ='ETAGE'     AND 
    s.ort                ='berlin'             
GROUP BY s.immobilien_id 
ORDER BY s.regionaler_zusatz, s.ort ASC LIMIT 0,3
Der ganze kram in der Where Klausel kann man weglassen, dann würd er halt alle holen. In diesem Beispiel ist die Where Klausel auch nich recht schlank, neben diesen angaben finden sich auch werte wie m2 von bis, miete oder Kaufpreis von bis, Anzahl der Zimmer von bis, Stadtbezirk usw.
Das teil kann also schonmal richtig Groß werden.

Diesen Query den ich hier zeige, ist das was ich Aktuell im einsatz habe und recht Performante ergebnisse erzielt. Jedoch muss ich bei 5000 Datensätzen in richtung letzter Seiten teilweise bis zu 3 oder 4 sec. warten (SQL Ausführungszeit).

Am liebsten würd ich nur mit LEFT JOIN Arbeiten, aber das ist derart Langsam :(

Grüße
 
Mit Explain habe ich schon gearbeitet, aber um Ehrlich zu sein, ich kapiert nicht was er mir damit sagen will.

Mit EXPLAIN kannst du sehen, ob die Indizes richtig gesetzt sind. Entscheidend sind die Felder: possible_keys, key und extra.
Vor allem die Sortierung mit ORDER BY kann sehr langsam werden, falls MySQL auf filesort zurückgreifen muss. Daher ist z.B. bei deiner Query ein Index auf s.regionaler_zusatz und s.ort wichtig.
 
Hi,

ach so, Du solltest natürlich Indizes auf Deine Fremdschlüsselspalten (immobilien_id) legen. Fehlen die, bremst das enorm, mehr als nicht indizierte Sortierspalten.

LG
 

Neue Beiträge

Zurück