2010-01-21 8 views
5

मैं अक्सर अपने आप निम्नलिखित की तरह एक SQL क्वेरी लिखने के लिए इच्छुक लगता है:एसक्यूएल: क्या यह प्रश्न ठीक है या क्या इसमें शामिल होने का एक और अधिक प्रभावी तरीका है?

SELECT body 
    FROM node_revisions 
where vid = (SELECT vid 
       FROM node 
       WHERE nid = 4); 

मैं जानता हूँ कि देखते हैं कि जुड़ जाता है और सामान तुम कर सकते हो, लेकिन वे बातें और अधिक जटिल बनाने के लिए लग रहे हैं। क्या ऐसा करने के लिए बेहतर तरीके से जुड़ रहे हैं? क्या यह अधिक कुशल है? समझने में आसान है?

+1

मैं शर्त लगा सकता हूं कि SQL सर्वर पर, उस क्वेरी और तर्कसंगत समकक्ष जुड़ने में समान क्वेरी निष्पादन योजनाएं होंगी। – Dana

उत्तर

7

में शामिल के बाद से डेटाबेस मन में सेट संचालन के साथ लिखा जाता है और अधिक कुशल हो जाते हैं (और संचालन सेट कर रहे हैं मिलती है)।

हालांकि, प्रदर्शन डेटाबेस से डेटाबेस में भिन्न होगा, टेबल कैसे संरचित किए जाते हैं, उनमें डेटा की मात्रा और क्वेरी द्वारा कितना वापस किया जाएगा।

यदि डेटा की मात्रा छोटी है, तो मैं शामिल होने के बजाय आपकी तरह एक सबक्वायरी का उपयोग करूंगा।

SELECT body 
FROM node_revisions nr 
INNER JOIN node n 
    ON nr.vid = n.vid 
WHERE n.nid = 4 

मैं, क्वेरी आप पोस्ट का उपयोग नहीं होगा, क्योंकि वहाँ एक nid = 4 है, जो इसे विफल करने के कारण होता है के साथ एक से अधिक नोड रिकॉर्ड का मौका है:

यहाँ एक में शामिल होने की तरह लग रही होगी।

मैं का प्रयोग करेंगे:

SELECT body 
FROM node_revisions 
WHERE vid IN (SELECT vid 
      FROM node 
      WHERE nid = 4); 

इस ज़्यादा पठनीय और समझा जा सकता है? इस मामले में, यह व्यक्तिगत वरीयता का मामला है।

+0

यह व्यक्तिगत वरीयता से अधिक तरीका है। मैं इन दो का उपयोग करके दो स्तंभों में शामिल होना चाहता हूं जो पठनीयता में तुलना करते हैं। ईमानदारी से, मेरे लिए, का उपयोग, एसक्यूएल में एक मूल वैचारिक समस्या का एक लक्षण हो सकता है। – ErikE

1
select 
    body 
from node_revisions A 
where exists (select 'x' 
       from Node B 
       Where A.Vid = B.Vid and B.NID=4) 
+2

यह बेहतर क्यों है? यह और अधिक जटिल लगता है। –

+0

यह अधिक जटिल है लेकिन यह भी वही काम नहीं कर रहा है। यह एक अर्ध-जुड़ाव है, जो कुछ मामलों में डेटाबेस सर्वर को कुछ अनुकूलन करने की अनुमति देता है। यह हमेशा मुख्य तालिका से केवल एक पंक्ति लौटाएगा इससे कोई फर्क नहीं पड़ता कि सबक्वायरी तालिका में कितनी मिलान पंक्तियां पाई जाती हैं। ध्यान दें कि आप सबक्वायरी में कॉलम को मुख्य क्वेरी में संदर्भित नहीं कर सकते हैं, लेकिन यह बात है: आप * अस्तित्व * की जांच कर रहे हैं, डेटा खींच नहीं रहे हैं।साथ ही, अगर बाहरी तालिका में सबक्वायरी तालिका में प्रति पंक्ति कई पंक्तियां होती हैं, तो मौजूदा वाक्यविन्यास कहीं अधिक कुशल हो सकता है क्योंकि यह केवल एक को ढूंढने के बाद रोक सकता है। – ErikE

+0

यह मूल क्वेरी के तर्कसंगत रूप से समतुल्य नहीं है। एकाधिक पंक्तियों को वापस करने वाले सबक्वायरी के मामले में, यह काम करेगा, और मूल क्वेरी विफल हो जाएगी। यह '=' के बजाय 'IN' के साथ एक क्वेरी के बराबर होगा। हालांकि, सभी आधुनिक इंजन सेमीफाइनल में 'EXISTS' और 'IN' दोनों को अनुकूलित कर सकते हैं। – Quassnoi

3

डेटाबेस में किसी भी प्रदर्शन से संबंधित प्रश्नों का जवाब यह निर्भर करता है है, और हम ओपी में विवरण पर कम कर रहे हैं। अपनी स्थिति के बारे में कोई विशेष को जानने का ...

में शामिल कर रहे हैं (गड़बड़) (इस प्रकार, इन अंगूठे के सामान्य नियम हैं) बेहतर और आसान समझने के लिए

  • किसी कारण से आप कई स्तंभ कुंजी की जरूरत है , आप शामिल होने के लिए एक और अभिव्यक्ति पर बस शामिल होने का उपयोग करना जारी रख सकते हैं।
  • यदि भविष्य में आपको वास्तव में सहायक डेटा में शामिल होने की आवश्यकता है, तो शामिल फ्रेमवर्क पहले से ही वहां है।
  • यह यह स्पष्ट करता है कि आप किस चीज में शामिल हो रहे हैं और जहां इंडेक्स लागू किए जाने चाहिए।
  • जुड़ने का उपयोग आपको जुड़ने के बारे में सोचने में बेहतर और बेहतर होने पर बेहतर बनाता है। के बारे में क्या टेबल खेल में कर रहे हैं स्पष्ट हैं

लिखित प्रश्नों के effiency साथ *

प्रश्नों आप लिख सकते हैं और क्या वास्तव में चलाने के हो जाता है थोड़ा एक दूसरे के साथ क्या करना है कुछ नहीं करना

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

    (* यह एक भयानक क्वेरी जो अक्षम है लिखने के लिए संभव है, लेकिन यह है कि क्या करना है। पागल एक खास किस्म ले जाता है)

    select 
        body 
    
    from node_revisions nr 
    
    join node n 
    on n.vid = nr.vid 
    
    where n.nid = 4 
    
  • 1

    नवीनतम MySQL 6.x कोड स्वचालित रूप से अभिव्यक्ति में है कि परिवर्तित कर देंगे में एक अंदरूनी, एक अर्द्ध में शामिल होने सबक्वेरी अनुकूलन का उपयोग कर काफी हद तक बराबर 2 बयान देने में शामिल हों:

    http://forge.mysql.com/worklog/task.php?id=3740

    लेकिन, वास्तव में यह लिख बाहर सुंदर करने के लिए सरल है, क्योंकि INNER जॉइन डिफ़ॉल्ट जॉइन प्रकार है, और ऐसा करने से सर्वर को इसे अनुकूलित करने पर भरोसा नहीं किया जाएगा (जो किसी कारण से नहीं तय कर सकता है और जो पोर्टेबल नहीं होगा)। सब बातों के समान होने के नाते, क्यों नहीं जाना के साथ:

    select body from node_revisions r, node n where r.vid = n.vid and n.node = 4 
    
    3

    मुझे लगता है कि जुड़ने को समझना आसान है और अधिक कुशल हो सकता है। आपका मामला बहुत आसान है, इसलिए यह शायद टॉस-अप है।

    SELECT body 
        FROM node_revisions 
        inner join node 
         on (node_revisions.vid = node.vid) 
        WHERE node.nid = 4 
    
    1

    मैं तुम्हें क्या लिखा है के साथ कुछ भी गलत नहीं दिख रहा है, और एक अच्छा अनुकूलक भी एक के लिए इसे बदल सकता है में शामिल होने अगर यह फिट देखता है: यहाँ मैं इसे कैसे लिखना होता है।

    1
    SELECT body 
    FROM node_revisions 
    WHERE vid = 
         (
         SELECT vid 
         FROM node 
         WHERE nid = 4 
         ) 
    

    इस क्वेरी तार्किक बराबर एक में शामिल होने का यदि और केवल यदि nid एक PRIMARY KEY है या एक UNIQUE बाधा द्वारा कवर किया जाता है।

    अन्यथा, प्रश्नों समान नहीं होते हैं: एक में शामिल होने हमेशा सफल होगा, अगर वहाँ अधिक है कि 1nid = 4 साथ node में पंक्ति रहे हैं, जबकि सबक्वेरी असफल हो जायेगी।

    यदि nidPRIMARY KEY है, तो JOIN और उपकुंजी का प्रदर्शन समान होगा।

    के मामले में एक में शामिल होने, node प्रमुख

    एक सबक्वेरी के मामले में किया जाएगा, सबक्वेरी एक बार निष्पादित किया जाएगा और मंच पार्स करने पर एक const में बदल दिया। दिलचस्प बात यह

    select body 
    from node_revisions nr, node n 
    where n.nid = 4 and nr.vid = n.vid 
    

    , एसक्यूएल सर्वर दोनों पर एक मामूली अलग क्वेरी योजना देता है:

    +0

    यूप, निड और vid अद्वितीय प्राथमिक कुंजी हैं। –

    +0

    '@ ब्रायन टी। हनान ': फिर प्रश्न समान हैं। 'जॉइन' और सबक्वायरी वही करेगी। – Quassnoi

    2

    एक में शामिल होने के दिलचस्प है:

    select body 
    from node_revisions nr 
    join node n on nr.vid = n.vid 
    where n.vid = 4 
    

    लेकिन आप भी एक के बिना एक में शामिल होने के शामिल होने व्यक्त कर सकते हैं [!] प्रश्न, जबकि एक क्लस्टर इंडेक्स स्कैन में शामिल है, "बिना किसी जुड़ने के शामिल हों" में क्लस्टर्ड इंडेक्स अपनी जगह तलाशता है, जो कम से कम इस मामले में better इंगित करता है!

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