JOIN कीवर्ड का उपयोग करना या न करना


45

निम्न SQL क्वेरी समान हैं:

SELECT column1, column2
FROM table1, table2
WHERE table1.id = table2.id;

SELECT column1, column2
FROM table1 JOIN table2 
ON table1.id = table2.id;

और निश्चित रूप से मैं कभी कोशिश की है हर DBMS पर एक ही क्वेरी योजनाओं में परिणाम।

लेकिन हर बार, मैं एक राय पढ़ता या सुनता हूं कि एक निश्चित रूप से दूसरे से बेहतर है। स्वाभाविक रूप से, इन दावों की व्याख्या के साथ कभी पुष्टि नहीं की जाती है।

जहां मैं काम करता हूं, दूसरे संस्करण को अधिकांश अन्य देवता पसंद करते हैं, और इसलिए मैं आश्चर्य को कम करने के लिए उस शैली की ओर भी जाता हूं। लेकिन मेरे दिल में, मैं वास्तव में पहला विचार कर रहा हूं (क्योंकि मैंने मूल रूप से इसे सीखा है)।

क्या इनमें से एक रूप दूसरे की तुलना में बेहतर है? यदि नहीं, तो एक के बाद एक उपयोग करने के क्या कारण होंगे?


1
क्यों नहीं इसे प्रोफाइल किया जाए और बाकी के लोगों को इसका नतीजा जानने दिया जाए? आम तौर पर बोल, प्रदर्शन बहुत अधिक शैली पसंद करते हैं।
डेमियन ब्रेख्त

3
"मैंने कभी भी कोशिश की है कि हर DBMS पर एक ही क्वेरी योजनाओं में परिणाम" अगर यह प्रदर्शन के मामले में एक जवाब हो सकता है, तो इसे stackoverflow.com पर पूछा होगा। अफसोस, वे एक ही प्रश्न हैं।
एकलकरण

आह .. याद आ गया कि :)
डेमियन ब्रेख्त

2
"विषय" का अर्थ "आपकी राय नहीं है"। मैंने इसे FAQ में निर्धारित मानदंडों को पूरा करने के लिए संपादित किया है ।
एरोन ने

मैं आश्चर्यचकित करने के लिए उस शैली की ओर भी रुख करता हूं, मुझे लगता है कि आपने सिर्फ अपने प्रश्न का उत्तर दिया है। आश्चर्य बुरा है।
पीटर बी

जवाबों:


60

मुझे लगता है कि दूसरा रूप बेहतर है। ऐसा इसलिए हो सकता है क्योंकि मैंने इसे सीखा है, मैं मानता हूँ, लेकिन मेरे पास एक ठोस कारण है - चिंताओं का अलग होना। जिन फ़ील्ड्स का आप उपयोग कर रहे हैं उन्हें उन तालिकाओं में शामिल करना, जहाँ क्लॉज़ प्रश्नों को समझने में कठिनाइयों का कारण बन सकते हैं।

उदाहरण के लिए, निम्नलिखित प्रश्न को लें:

select *
from table1, table2, table3, table4
where table1.id = table2.id
and table2.id = table3.id
and table3.id = table4.id
and table1.column1 = 'Value 1'

उपरोक्त क्वेरी में तालिका में शामिल होने की स्थिति और वास्तविक व्यापार तर्क स्थितियां हैं जो सभी एक ही स्थान पर संयुक्त हैं। एक बड़ी क्वेरी के साथ, यह समझना बहुत मुश्किल हो सकता है।

हालाँकि, अब यह कोड लें:

select *
from table1 join table2 on table1.id = table2.id
join table3 on table2.id = table3.id
join table4 on table3.id = table4.id
where table1.column1 = 'Value 1'

इस मामले में, तालिकाओं के साथ क्या करना है या वे कैसे संबंधित हैं, यह सब खंड से अलग-थलग है, जबकि क्वेरी प्रतिबंध के लिए वास्तविक व्यापार तर्क जहां खंड में है। मुझे लगता है कि यह अभी और अधिक समझने योग्य है, विशेष रूप से बड़े प्रश्नों के लिए।


यह विशेष रूप से एक बार करने का एकमात्र समझदार तरीका है जब आप पिछले दो तालिकाओं को प्राप्त करते हैं, या बाएं, दाएं और पूर्ण जोड़ों के संयोजन की आवश्यकता होती है।
एग्लासमैन 22

5
+1 "चिंताओं के पृथक्करण" के लिए, डेटा को एक साथ लाता है, जहाँ

39

ज्वाइन सिंटैक्स ने 1992 में पुराने कॉमा सिंटैक्स को बदल दिया। कॉमा सिंटैक्स के साथ कोड लिखने का वर्तमान में कोई कारण नहीं है। आप कुछ भी हासिल नहीं करते हैं और आप कुछ समस्याओं के अधीन हैं जो आपके पास स्पष्ट वाक्य रचना के साथ नहीं हैं।

पहली जगह में जब आप अधिक जटिल प्रश्न प्राप्त करते हैं तो एक आकस्मिक हालत में जहां एक शर्त को याद करके क्रॉस ज्वाइन करना बहुत आसान होता है। यह कुछ ऐसा है जो स्पष्ट रूप से शामिल होने वाला सिंटैक्स होने से रोक सकता है क्योंकि आपको सिंटैक्स त्रुटि मिलेगी।

यदि आप एक क्रॉस जॉइन का इरादा रखते हैं, तो स्पष्ट ज्वाइन सिंटैक्स उस स्पष्ट को बना देगा जबकि निहित सिंटैक्स में रखरखाव करने वाला कोई व्यक्ति आपको यह मान सकता है कि कहां क्लॉज जोड़ना भूल गया।

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

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

अंत में कई लोग जो निहित जोड़ का उपयोग करते हैं वे वास्तव में जुड़ाव को नहीं समझते हैं। यह एक महत्वपूर्ण समझ है जो आपको एक डेटाबेस को प्रभावी ढंग से क्वेरी करने के लिए होनी चाहिए।


विवरण के लिए आपका धन्यवाद। जब मुझे सिखाया गया था तो हमें दोनों वाक्यविन्यास दिखाए गए थे, लेकिन अंतर स्पष्ट नहीं किया गया था। मैं कभी-कभी गायब होने के साथ प्रश्नों का उत्पादन करने में कामयाब रहा, जिसमें स्पष्ट रूप से केवल पहली जगह पर स्पष्ट रूप से शामिल होने पर लेखन की मात्रा बढ़ गई होगी।
अज़ीब

8

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

लगभग छह ऐसी जोड़ियों के बाद, संख्या इतनी महान है कि क्वेरी की योजना बनाने का समय ध्यान देने योग्य हो सकता है, और लगभग दस के बाद, आशावादी योजनाओं की एक विस्तृत खोज से एक संभाव्य खोज पर स्विच करेगा, और इष्टतम योजना पर नहीं आ सकता है ।

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

ध्यान दें, डिफ़ॉल्ट व्यवहार या तो मामले में समान है, और वैकल्पिक योजना प्राप्त करने के लिए अलग परिणाम प्राप्त करने के लिए dbms के आंतरिक और तालिकाओं की ख़ासियत का ज्ञान आवश्यक है


2
हालाँकि, आपने उन डॉक्स को थोड़ा गलत समझा है। सबसे पहले, वास्तव में तीन थ्रेसहोल्ड हैं। जैसा कि आपने बताया कि GEQO में एक फायर होता है; अन्य दो (और पतन की सीमा से जुड़ें) प्लानर स्टिक को अंत में फिर से व्यवस्थित करने के बजाय लागू अनुक्रमितों को चुनने के लिए छड़ी बनाते हैं। दूसरे और महत्वपूर्ण रूप से, प्रश्नों को फिर से लिखा जाता है क्योंकि वे पार्स होते हैं। इससे पहले वाले प्रश्नों के परिणाम सामने आते हैं, ठीक उसी क्वेरी ट्री में जिसे दूसरे के रूप में देखा गया है - थ्रेसहोल्ड तो पीजी को यह बता देता है कि उसे जॉइन करने के लिए री-ऑर्डर करने की कोशिश करनी चाहिए या नहीं।
डेनिस डे बर्नार्डी

8

अच्छी तरह से यहाँ सेट सिद्धांत यह है:

जब आप दो (या अधिक) तालिका नामों को अलग करने के लिए अल्पविराम का उपयोग करते हैं, तो आप कार्टेसियन उत्पाद क्या हैं। 'बाएँ' तालिका की प्रत्येक पंक्ति सही तालिका के साथ 'मिलान' (संक्षिप्त) होगी।

अब अगर आप किसी चीज़ को क्लॉज़ में लिखते हैं, तो यह इस 'कॉन्टेक्नेशन' पर एक शर्त लगाने जैसा है जिसमें बताया गया है कि कौन सी पंक्तियों को 'कॉनकटेनेट' करना है।

यह वास्तव में पंक्तियों को "ज्वाइन करना" है और इसलिए इससे जुड़ने वाला कीवर्ड जो एक अधिक पठनीय वाक्यविन्यास प्रदान करने में मदद करता है और अधिक समझने योग्य है कि आप 'वास्तव में' कुछ सामान्य मूल्यों पर जुड़ना चाहते हैं। जैसा @Dustin ने ऊपर स्पष्ट किया है।

अब, हर DBMS स्मार्ट है, यह कार्टेशियन उत्पाद की गणना पहले नहीं करता है और फिर डेटा (बेहद बेकार) को फ़िल्टर करता है, बल्कि क्वेरी संरचना के आधार पर ऐसा करता है। केवल एक चीज जो मैं सोच सकता हूं, जब आप इसे 'ज्वाइन' करने के लिए कहेंगे तो यह जॉइनिंग एक्टिविटी को स्पष्ट करने जैसा है और संभवत: कोड को तेजी से चलाने में मदद करता है (कितना करके? आपको इसे प्रोफाइल करना होगा और देखना होगा) लेकिन अंदर? अल्पविराम से अलग किया गया मामला, इसके लिए कुछ समय की जरूरत है कि वह 'इष्टतम' रणनीति बना सके। मैं गलत हो सकता हूं, लेकिन मैं सिर्फ एक शिक्षित अनुमान लगा रहा हूं कि कोई इसे कैसे कोड करेगा ...


5

मुझे लगता है कि आम तौर पर उस मामले के लिए JOIN स्टेटमेंट का उपयोग करना बेहतर होता है।

अगर, भविष्य में, ऐसी स्थिति उत्पन्न होती है, जिसमें INNER JOIN से OUTER JOIN तक स्टेटमेंट बदलने की आवश्यकता होती है, तो दूसरे स्टेटमेंट के साथ ऐसा करना बहुत आसान होगा।


3

कोई भी आरडीबीएमएस निष्पादन के मामले में उन्हें समान बनाने जा रहा है। यह नीचे आता है कि क्या कोई अधिक पठनीय और अभिव्यंजक है।

JOIN का उपयोग करें ताकि यह स्पष्ट हो जाए कि मिलान में क्या शामिल है और वास्तविक चयन क्या है, जैसे:

select name, deptname
from people p, departments d
where p.deptid = d.id and p.is_temp = 'Y'

बनाम

select name, deptname
from people p
    inner join departments d on p.deptid = d.id
where p.is_temp = 'Y'

बाद का मामला यह तुरंत स्पष्ट कर देता है कि कौन सी सम्मिलित शर्त है, और कौन सा चयन मानदंड है।


1

मैंने केवल एक बार दोनों परिणामों को अनुकूलन के एक अलग सेट में देखा है और यदि स्मृति कार्य करती है तो यह वास्तव में बालों वाली क्वेरी पर ms-sql2k में था। उस एक उदाहरण में * = के साथ पुराने रूप का उपयोग किया गया, जिसके परिणामस्वरूप लगभग 4x तेज़ प्रदर्शन हुआ। हमारे Microsoft तकनीक के लोगों सहित कोई भी कभी भी यह क्यों समझा सकता है। एमएस लोगों ने इसे एक गलती करार दिया। मैंने इसे फिर कभी नहीं देखा।

चूंकि अधिकांश आरडीबीएमएस पूर्ण कार्टिसियन नहीं करने के लिए पर्याप्त स्मार्ट हैं, इसलिए सबसे बड़ा कारण मैं इसका उपयोग न करने के बारे में सोच सकता हूं (इसके अलावा यह मूल्यह्रास है) यह है कि 30-35 से कम उम्र के अधिकांश लोगों के साथ जिन्होंने मैंने कभी काम नहीं किया है। पुराने रूप से पहले और बहुत बुरी तरह से हार जाते हैं जब वे इसका सामना करते हैं।


बेशक, जो सिंटैक्स में शामिल हो गया, उसने कभी भी सही परिणाम प्रदान नहीं किया मज़बूती से (SQL सर्वर 2000 के लिए BOL देखें) तो भी अगर यह तेज़ होता, तो मैं इसे बदल देता।
HLGEM

मैंने कभी इसका सामना नहीं किया, और तारांकन के साथ खोज करना कभी भी अच्छा नहीं होता है, क्या आपके पास एक उदाहरण है?
बिल

-1

पुरानी शैली को हटा दिया गया है, आपको इसका उपयोग नहीं करना चाहिए।

इस बात पर भी बहस नहीं होनी चाहिए कि कौन बेहतर है या नहीं। नए कोड को पुराने सिंटैक्स का उपयोग नहीं करना चाहिए।


मुझे लगता है कि यह जवाब वास्तव में यह कहे बिना कुछ भी नहीं जोड़ता है कि इसे क्यों निकाला गया और इसका उपयोग नहीं किया जाना चाहिए।
रेमकोगर्लिच

1
@RemcoGerlich क्यों हटा दिया गया है यहाँ चर्चा के अधीन नहीं है। यहाँ चर्चा चल रही है कि क्या पुराने या नए सिंटैक्स का उपयोग करना है। एक बेहतर है या नहीं तो दूसरा है या नहीं: आप पुराने वाक्यविन्यास का उपयोग नहीं करना चाहिए। क्यों सवाल एक और चर्चा है। (एक जिसे 20 साल पहले सुलझा लिया गया है।)
पीटर बी

-4

अधिक ट्रिक सिंटैक्स का एक कारण यह है कि यह अधिक ट्रिक है, इसलिए यदि आप इसके साथ सहज हैं तो इसे पढ़ना आसान है। मैं वर्बोज़ केस के बारे में सोचता हूँ जैसे कि COBOL में अंकगणित को लिखने के समान है, जैसे MULTIPLY A BY B BIVING C।


डाउनवोटर्स: क्या इस प्रतिक्रिया में कुछ तथ्यात्मक रूप से गलत है, या वे सिर्फ "डाउनवोट्स" से आपसे असहमत थे?
एडम लिबुसा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.