2009-11-27 27 views
11

तो ... कौन सा तेज़ है (कुल मूल्य कोई मुद्दा नहीं है), और अनुक्रमित हैं।बाएं तेजी से जुड़ें या अंदरूनी तेजी से शामिल हों?

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

का उपयोग करते हुए वाम शामिल:

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

यहाँ है यहाँ वास्तविक क्वेरी है .. दोनों एक ही परिणाम

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

आप उन्हें दोनों क्यों नहीं चलाते और हमें बताते हैं कि तेज़ कौन सा है? – Welbog

+0

इस प्रश्न को दोहराया जाना चाहिए, "मैं कैसे पता लगा सकता हूं कि कौन सी क्वेरी तेजी से चलती है?" –

+0

क्या ये ईवेंट परिणाम के समान सेट को वापस करते हैं? (कॉलम, पंक्तियां नहीं) – JMD

उत्तर

9

यह निर्भर करता है वापसी; उन्हें खोजने के लिए दोनों चलाओ; फिर स्पष्टीकरण के लिए 'चयन व्याख्या करें' चलाएं।

वास्तविक प्रदर्शन अंतर आईडी वाला में कितने पंक्तियों = '12345' कोई मिलता-जुलता रिकॉर्ड बी में और सी

अद्यतन है पर निर्भर करता है से "वस्तुतः न के बराबर" को "बहुत महत्वपूर्ण" हो सकती हैं (पोस्ट क्वेरी योजनाओं के आधार पर)

जब आप इनर जॉइन का उपयोग करते हैं तो इससे कोई फर्क नहीं पड़ता (परिणाम-वार, प्रदर्शन-वार नहीं) किस तालिका से शुरू होता है, इसलिए ऑप्टिमाइज़र उस व्यक्ति को चुनने का प्रयास करता है जो सोचता है कि यह सबसे अच्छा प्रदर्शन करेगा । ऐसा लगता है कि आपके पास सभी उचित पीके/एफके कॉलम पर इंडेक्स हैं और आपके पास friend_events.userid पर कोई अनुक्रमणिका नहीं है या userid = '13006' के साथ बहुत सारे रिकॉर्ड हैं और इसका उपयोग नहीं किया जा रहा है; किसी भी तरह से अनुकूलक तालिका को "आधार" के रूप में कम पंक्तियों के साथ चुनता है - इस मामले में यह zcms_users है।

जब आप बाएं जॉइन का उपयोग करते हैं तो मामले (परिणाम-वार) किस तालिका से शुरू होता है; इस प्रकार friend_events चुना जाता है। अब क्यों इसमें कम समय लगता है जिस तरह से मुझे पूरा यकीन नहीं है; मुझे अनुमान है कि friend_events.userid स्थिति मदद करता है। यदि आप एक इंडेक्स जोड़ना चाहते थे (क्या यह वास्तव में वर्चर है, बीटीडब्ल्यू? न्यूमेरिक नहीं है?) उस पर, आपका इनर जॉइन अलग-अलग व्यवहार कर सकता है (और तेज़ हो सकता है)।

+0

मैंने इसे चलाया है। ऐसा लगता है कि आंतरिक एक रास्ता धीमा है। लेकिन यह नहीं है कि आंतरिक होना चाहिए bette rthan बाएं शामिल हो? – Murvinlai

+0

क्या आप दोनों प्रश्नों के लिए "चयन व्याख्या" के परिणाम पोस्ट कर सकते हैं? – ChssPly76

2

क्वेरी योजना देखने के लिए EXPLAIN का उपयोग करें। यह शायद दोनों मामलों के लिए एक ही योजना है, इसलिए मुझे संदेह है कि इससे कोई फर्क नहीं पड़ता है, ऐसा लगता है कि कोई पंक्ति नहीं है जो मेल नहीं खाती है। लेकिन ये दो अलग-अलग प्रश्न हैं इसलिए वास्तव में उनकी तुलना करने के लिए यह समझ में नहीं आता है - आपको केवल सही का उपयोग करना चाहिए।

"बाएं जॉइन" के बजाय "इनर जॉइन" कीवर्ड का उपयोग क्यों न करें?

3

INNER जॉइन को ए से किसी भी रिकॉर्ड को हटाने के लिए अतिरिक्त जांच करना है, जिसमें बी और सी में मिलान करने वाले रिकॉर्ड नहीं हैं। शुरुआत में रिकॉर्ड किए गए रिकॉर्ड की संख्या के आधार पर इसका प्रभाव हो सकता है।

1

LEFT JOINA से सभी डेटा दिखाता है और केवल स्थिति ही सत्य होने पर B/C से डेटा दिखाता है। INNER JOIN के लिए, इसे tables दोनों पर कुछ अतिरिक्त जांच करनी है। तो, मुझे लगता है कि बताता है कि क्यों LEFT JOIN तेज है।

संबंधित मुद्दे