2009-11-27 6 views
11

Also ... welcher ist schneller (NULL Wert ist kein Problem), und sind indiziert.Links JOIN schneller oder Inner Join schneller?

SELECT * FROM A 
    JOIN B b ON b.id = a.id 
    JOIN C c ON c.id = b.id 
WHERE A.id = '12345' 

Mit Left Joins:

SELECT * FROM A 
LEFT JOIN B ON B.id=A.bid 
LEFT JOIN C ON C.id=B.cid 
WHERE A.id = '12345' 

Hier ist die eigentliche Abfrage ist Hier ist .. beide das gleiche Ergebnis zurück

Query (0.2693sec) : 
    EXPLAIN EXTENDED SELECT * 
    FROM friend_events, zcms_users, user_events, 
    EVENTS WHERE friend_events.userid = '13006' 
    AND friend_events.state =0 
    AND UNIX_TIMESTAMP(friend_events.t) >=1258923485 
    AND friend_events.xid = user_events.id 
    AND user_events.eid = events.eid 
    AND events.active =1 
    AND zcms_users.id = user_events.userid 

EXPLAIN 

    id select_type table type possible_keys key key_len ref rows Extra 
    1 SIMPLE zcms_users ALL PRIMARY NULL NULL NULL 43082 
    1 SIMPLE user_events ref PRIMARY,eid,userid userid 4 zcms_users.id 1 
    1 SIMPLE events eq_ref PRIMARY,active PRIMARY4 user_events.eid 1 Using where 
    1 SIMPLE friend_events eq_ref PRIMARY PRIMARY 8 user_events.id,const 1 Using where 



    LEFTJOIN QUERY: (0.0393 sec) 

    EXPLAIN EXTENDED SELECT * 
    FROM `friend_events` 
    LEFT JOIN `user_events` ON user_events.id = friend_events.xid 
    LEFT JOIN `events` ON user_events.eid = events.eid 
    LEFT JOIN `zcms_users` ON user_events.userid = zcms_users.id 
    WHERE (
    events.active =1 
    ) 
    AND (
    friend_events.userid = '13006' 
    ) 
    AND (
    friend_events.state =0 
    ) 
    AND (
    UNIX_TIMESTAMP(friend_events.t) >=1258923485 
    ) 


EXPLAIN 
    id select_type table type possible_keys key key_len ref rows Extra 
    1 SIMPLE friend_events ALL PRIMARY NULL NULL NULL 53113 Using where 
    1 SIMPLE user_events eq_ref PRIMARY,eid PRIMARY 4 friend_events.xid 1 Using where 
    1 SIMPLE zcms_users eq_ref PRIMARY PRIMARY 4 user_events.userid 1 
    1 SIMPLE events eq_ref PRIMARY,active PRIMARY 4 user_events.eid 1 Using where 
+1

Warum fährst du nicht beide und sagst uns, welche schneller ist? – Welbog

+0

Diese Frage sollte neu formuliert werden: "Wie kann ich herausfinden, welche Abfrage schneller ausgeführt wird?" –

+0

Geben diese Ereignisse die gleichen Ergebnisse zurück? (Spalten, nicht Zeilen) – JMD

Antwort

9

Es hängt davon ab; Führe sie beide, um es herauszufinden; Führen Sie dann eine Erklärung aus, um eine Erklärung zu erhalten.

Der Unterschied tatsächliche Leistung kann von „praktisch nicht existent“ bis „ziemlich signifikant“, je nachdem, wie viele Zeilen in A mit id = ‚12345‘ liegt keine passenden Datensätze in B und C.

-Update haben (basierend auf geposteten Abfrageplänen)

Wenn Sie INNER JOIN verwenden, spielt es keine Rolle, welche Tabelle zu beginnen ist, also versucht der Optimierer diejenige auszuwählen, von der er denkt, dass sie am besten funktioniert . Anscheinend haben Sie Indizes für alle geeigneten PK/FK-Spalten und Sie haben entweder keinen Index für friend_events.userid oder es gibt zu viele Datensätze mit userid = '13006' und es wird nicht verwendet. In beiden Fällen wählt der Optimierer die Tabelle mit weniger Zeilen als "Basis" aus - in diesem Fall ist es zcms_users.

Wenn Sie LEFT JOIN verwenden, ist es tut (ergebnismäßig), welche Tabelle zu beginnen; somit wird friend_events ausgewählt. Jetzt warum es dauert weniger Zeit so bin ich nicht ganz sicher; Ich schätze friend_events.userid Zustand hilft. Wenn Sie einen Index hinzufügen würden (ist es wirklich varchar, btw? Nicht numerisch?), Dann könnte sich Ihr INNER JOIN auch anders verhalten (und schneller werden).

+0

Ich habe es ausgeführt. es scheint, als wäre das Innere viel langsamer. Aber ist es nicht so, dass das Innere besser sein sollte als Linke mitmachen? – Murvinlai

+0

Können Sie die Ergebnisse von "explain select" für beide Abfragen posten? – ChssPly76

2

Verwenden Sie EXPLAIN, um den Abfrageplan anzuzeigen. Es ist wahrscheinlich der gleiche Plan für beide Fälle, also bezweifle ich, dass es viel Unterschied macht, vorausgesetzt, es gibt keine Zeilen, die nicht übereinstimmen. Aber das sind zwei verschiedene Abfragen, so dass es wirklich keinen Sinn macht, sie zu vergleichen - Sie sollten nur die richtige verwenden.

Warum nicht das Schlüsselwort "INNER JOIN" anstelle von "LEFT JOIN" verwenden?

3

Der INNER JOIN muss eine zusätzliche Prüfung durchführen, um alle Datensätze aus A zu entfernen, die keine übereinstimmenden Datensätze in B und C haben. Abhängig von der Anzahl der ursprünglich von A zurückgegebenen Datensätze könnte dies Auswirkungen haben.

1

LEFT JOIN zeigt alle Daten von A und zeigt nur Daten von B/C nur, wenn die Bedingung wahr ist. Wie für INNER JOIN, muss es einige zusätzliche Überprüfung für beide tables. Also, ich denke, das erklärt, warum LEFT JOIN schneller ist.