इनर बनाम बनाम


257

क्या प्रदर्शन (ओरेकल में) के बीच अंतर है

Select * from Table1 T1 
Inner Join Table2 T2 On T1.ID = T2.ID

तथा

Select * from Table1 T1, Table2 T2 
Where T1.ID = T2.ID

?


1
सिर्फ रिकॉर्ड के लिए, मैंने देखा है कि क्वेरीज़ अलग-अलग परिणामों को एक
जॉइन्ट

12
@BlackTigerX: अलग परिणाम? क्या इसमें कोई बाहरी शामिल था? क्योंकि मैं यह नहीं देखता हूं inner join ... onकि whereखंड में सम्‍मिलित सम्‍मिलित मानदंड डालने के बीच अलग-अलग परिणाम कैसे होंगे ।
शैनन सेवरेंस

पुराने डेटाबेस के पुराने संस्करण में मौजूद नहीं हैjoin
माजिदतैरी

2
@MajidTaheri: ओरेकल के एक पुराने संस्करण की आप कितनी पुरानी बात कर रहे हैं? Oracle द्वारा समर्थित कोई भी संस्करण JOIN अंकन का समर्थन करता है।
जोनाथन लेफ़लर

सामान्य उत्तर या तुच्छ मामलों के आधार पर सर्वोत्तम प्रथाओं के लिए देखें। अधिक जटिल के साथ "री-मैच" देखना पसंद करेंगे, जहां कई एंडलॉइड स्थितियां शामिल होंगी। कम से कम SQL सर्वर के साथ एक क्रॉसओवर बिंदु है।
क्रोकेक

जवाबों:


195

नहीं! एक ही निष्पादन योजना, इन दो तालिकाओं को देखें:

CREATE TABLE table1 (
  id INT,
  name VARCHAR(20)
);

CREATE TABLE table2 (
  id INT,
  name VARCHAR(20)
);

आंतरिक जुड़ने का उपयोग करते हुए क्वेरी के लिए निष्पादन योजना:

-- with inner join

EXPLAIN PLAN FOR
SELECT * FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id;

SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);

-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2

और WHERE क्लॉज का उपयोग करते हुए क्वेरी के लिए निष्पादन योजना।

-- with where clause

EXPLAIN PLAN FOR
SELECT * FROM table1 t1, table2 t2
WHERE t1.id = t2.id;

SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);

-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2

4
मैं वास्तव में यह देखना चाहता हूं कि इस बारे में ओरेकल का कोई आधिकारिक दस्तावेज है या नहीं
कवर

68

यदि क्वेरी ऑप्टिमाइज़र अपना काम सही कर रहा है, तो उन प्रश्नों के बीच कोई अंतर नहीं होना चाहिए। वे एक ही वांछित परिणाम निर्दिष्ट करने के लिए सिर्फ दो तरीके हैं।


22
हाँ, प्रदर्शन समान होना चाहिए। लेकिन तालिका 1, तालिका 2 का चयन करें * ... वाक्यविन्यास EVIL है!
जोएल कोएहॉर्न

2
मुझे SQL-92 सिंटैक्स की तुलना में INNER JOINS के लिए समझना बहुत आसान लगता है। आपकी माइलेज भिन्न हो सकती है।
क्रेग ट्रेडर

25
मुझे INNER JION की तुलना में WHERE सिंटैक्स पढ़ने में आसान लगता है - मुझे लगता है कि यह Vegemite जैसा है। दुनिया में ज्यादातर लोगों को शायद यह घृणित लगता है लेकिन बच्चों ने इसे प्यार से खाया।
स्कॉटकर

3
Vegemite वास्तव में बुरा है, लेकिन फिर मैं हाथापाई प्यार करता हूँ। जाओ पता लगाओ।
स्टिंगजैक 12

2
@Darryl मुझे लगता है कि JOINपढ़ने के लिए आसान कर रहे हैं क्योंकि तालिकाओं में शामिल होने के लिए WHEREशर्त खंड में "कहीं" के बजाय तुरंत वहाँ परिभाषित किया गया है। मैं WHEREडेटासेट्स (जैसे WHERE DATE > (SYSDATE - 1)) को सीमित करने के लिए क्लॉज को आरक्षित करना पसंद करता हूं, इसके बजाय यह भी परिभाषित करता है कि टेबल एक-दूसरे से कैसे संबंधित हैं (जैसे WHERE T1.ID = T2.ID)। एक छोटी सी तालिका के लिए जैसे प्रश्न में उदाहरण से बहुत कम फर्क पड़ता है, लेकिन कई तालिकाओं और कई स्थितियों से जुड़े बड़े प्रश्नों के लिए, मुझे लगता है कि यह क्वेरी को समझने में बहुत आसान बनाता है।
काल्पनिक

61

वे बिल्कुल समान होना चाहिए। हालाँकि, एक कोडिंग अभ्यास के रूप में, मैं बल्कि Join देखूंगा। यह स्पष्ट रूप से आपके इरादे को स्पष्ट करता है,


8
मैं सहमत हूँ। विशेष रूप से यदि आप कई तालिकाओं में शामिल हो रहे हैं, तो एक स्पष्ट कथन को पार्स करना बहुत आसान है यदि आप स्पष्ट जोड़ कर रहे हैं।
पॉल मोरी

13
वास्तव में। जुड़ने से डेटा के दो सेटों के बीच एक अर्थ संबंधी संबंध का प्रतिनिधित्व होता है, लेकिन एक फ़िल्टर किए गए सेट का पता चलता है। +1
एइटोइन यूनाइट

26

का उपयोग करते हुए JOIN, बनाता है कोड को पढ़ने में आसान है, क्योंकि यह की आत्म व्याख्यात्मक।

गति में कोई अंतर नहीं है ( मैंने अभी इसका परीक्षण किया है ) और निष्पादन योजना समान है।


धन्यवाद। मैं इस दो तरीकों के बीच गति संपीड़न की तलाश कर रहा था।
फरहाद नवाज़दान

14

मैं ओरेकल के बारे में नहीं जानता, लेकिन मुझे पता है कि पुराने सिंटैक्स को SQL सर्वर में पदावनत किया जा रहा है और अंततः गायब हो जाएगा। इससे पहले कि मैं एक नई क्वेरी में उस पुराने वाक्यविन्यास का उपयोग करता, मैं यह जांचता कि ओरेकल के साथ क्या करना है।

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

और फिर से मैं ओरेकल को विशेष रूप से नहीं जानता, लेकिन मुझे पता है कि पुरानी शैली के एसक्यूएल सर्वर संस्करण को छोड़ दिया गया है जो SQL Server 2000 में भी त्रुटिपूर्ण है और असंगत परिणाम देता है (कभी-कभी बाएं ज्वाइन कभी-कभी क्रॉस जॉइन होता है), इसलिए यह कभी नहीं होना चाहिए उपयोग किया गया। उम्मीद है कि ओरेकल एक ही मुद्दे को पीड़ित नहीं करता है, लेकिन निश्चित रूप से बाएं और दाएं जोड़ पुराने सिंटैक्स में ठीक से व्यक्त करने के लिए कठिन हो सकते हैं।

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


1
आमीन भाई। जॉयर्स के साथ नीचे !!
स्कॉटकर

14

[एक बोनस बिंदु के लिए ...]

JOIN सिंटैक्स का उपयोग करने से आप अधिक आसानी से कमेंट पर टिप्पणी कर सकते हैं क्योंकि यह एक लाइन में शामिल है। यदि आप एक जटिल क्वेरी डीबग कर रहे हैं तो यह उपयोगी हो सकता है

जैसा कि बाकी सभी कहते हैं, वे कार्यात्मक रूप से समान हैं, हालांकि जोइन इरादे के बयान से अधिक स्पष्ट है। इसलिए यह हो सकता है कुछ मामलों में वर्तमान ओरेकल संस्करणों (मैं पता नहीं करता है, तो यह करता है) में या तो क्वेरी अनुकूलक मदद, यह हो सकता है Oracle (कोई किसी भी विचार है) के भविष्य के संस्करणों में क्वेरी अनुकूलक मदद, या यह हो सकता है, तो मदद आप डेटाबेस आपूर्तिकर्ता बदल जाते हैं।


2
या ... आसानी से INNER JOINS को LEFT JOINS में बदल दें, ताकि आप देख सकें कि कौन सी जॉइन आपको अपेक्षित पंक्तियों से चूकने का कारण बन रही है। मैं ऐसा इसलिए करता हूं क्योंकि मैं एक बार में पूरी क्वेरी करता हूं। यदि आप INNER JOINS पर टिप्पणी करते हैं, तो आप को समाप्त करने की प्रक्रिया करनी होगी। इसमें अधिक समय लगता है। लेकिन +1 आपके लिए क्योंकि यह INNER JOINS के लिए पठनीयता से अलग मेरे पसंदीदा कारणों में से एक है!
मैथ्यू मैकपीक

13

वे तार्किक रूप से समान हैं, लेकिन Oracle के पहले संस्करणों में, जिन्होंने ANSI सिंटैक्स को अपनाया था, अधिक जटिल मामलों में अक्सर इसके साथ कीड़े थे, इसलिए आप कभी-कभी इसका उपयोग करते समय Oracle डेवलपर्स से प्रतिरोध का सामना करेंगे।


ओरेकल के पहले संस्करणों में इसके साथ कीड़े थे? कितनी जल्दी? क्या संस्करण है?
स्कॉटकर

मेटलिंक में विवरण हैं ... वे सभी जगह पॉप-अप करते हैं।
डेविड एल्ड्रिज

7

प्रदर्शन समान होना चाहिए, लेकिन मैं बाहरी स्पष्टता में शामिल होने पर बेहतर स्पष्टता के कारण जॉइन-वर्जन का उपयोग करने का सुझाव दूंगा।

साथ ही अनजाने कार्टेसियन उत्पादों को जॉइन-वर्जन के उपयोग से बचा जा सकता है।

एक तीसरा प्रभाव SQL को सरल WHERE-कंडीशन के साथ पढ़ना आसान है।


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

6

यह मत भूलो कि ओरेकल में, बशर्ते कि मुख्य विशेषताओं को दोनों तालिकाओं में एक ही नाम दिया गया हो, आप इसे इस प्रकार भी लिख सकते हैं:

select *
from Table1 inner join Table2 using (ID);

इसकी भी समान क्वेरी योजना है।


मैंने संस्करण को वापस ले लिया क्योंकि पिछले संशोधन ने उत्तर का अर्थ बदल दिया था
जुआन

5

ऐसे परिदृश्य में जहाँ तालिकाएँ 3 सामान्य रूप में होती हैं, तालिकाओं के बीच में परिवर्तन नहीं होना चाहिए। यानी CUSTOMERS और PAYMENTS को हमेशा एक जैसा रखना चाहिए।

हालाँकि, हमें फ़िल्टर से जुड़ने में अंतर करना चाहिए । जुड़ाव रिश्तों के बारे में हैं और फ़िल्टर पूरे विभाजन के बारे में हैं।

कुछ लेखक, मानक (यानी जिम मेल्टन; एलन आर। साइमन (1993) का जिक्र करते हैं। नई एसक्यूएल को समझना। एक पूर्ण गाइड। मॉर्गन कॉफमैन। पीपी। 11–12। आईएसबीएन 978-1-55860-245-8।) , जोकर से अलग तालिकाओं में संयुक्त वाक्यविन्यास को अपनाने के लाभों के बारे में लिखा है।

मैं इस बात से पूरी तरह सहमत हूं।

SQL लिखने और उसी परिणाम को प्राप्त करने के कई तरीके हैं, लेकिन टीमवर्क करने वालों में से कई के लिए, स्रोत कोड की सुगमता एक महत्वपूर्ण पहलू है, और निश्चित रूप से अलग कैसे विशिष्ट तालिकाओं से एक दूसरे से संबंधित तालिकाओं को स्पष्ट करने के अर्थ में एक बड़ी छलांग थी कोड।


इनर जॉइन का मतलब होता है क्रॉस क्रॉस जहां। कोमा कीवर्ड जॉइन की तुलना में कम पूर्वता के साथ क्रॉस जॉइन है। बनाम "फ़िल्टर" आंतरिक जुड़ाव के लिए अप्रासंगिक है। NF क्वेरी करने के लिए अप्रासंगिक हैं। मानक में कुछ भी नहीं कोमा से अधिक कीवर्ड जुड़ता है। तुच्छ अनुकूलन पर और जहां एक जैसे व्यवहार करते हैं। यह उत्तर गलत धारणाओं का एक समूह है।
दोपहर

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

4

PostgreSQL में, निश्चित रूप से कोई अंतर नहीं है - वे दोनों एक ही क्वेरी योजना के बराबर हैं। मुझे यकीन है कि 99% ओरेकल के लिए भी यही है।


2

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


2

कार्यात्मक रूप से वे वही हैं जो कहा गया है। हालांकि मैं मानता हूं कि जो आप करना चाहते हैं उसका वर्णन करने के लिए ज्वाइन करना बेहतर है। बहुत बार मैंने सोचा है कि मुझे पता था कि मैं कैसे कुछ करना चाहता था जब तक कि मैंने जॉन्स करना शुरू नहीं किया और मुझे एहसास हुआ कि मैं अपने सिर में मूल एक से अलग क्वेरी करना चाहता था।


1

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


यह एक समस्या के साथ विचारों की तुलना में जुड़ने की तुलना में अधिक है।
15

0

यद्यपि दो प्रश्नों की पहचान स्पष्ट प्रतीत होती है लेकिन कभी-कभी कुछ अजीब चीजें होती हैं। मुझे पता चला है कि क्वेरी wich में अलग-अलग निष्पादन योजनाएं हैं, जब ज्वाइंट से WHERE में Oracle 10g (WHERE प्लान के लिए बेहतर है) में शामिल होने के लिए आगे बढ़ रहे हैं, लेकिन मैं सरलीकृत तालिकाओं और डेटा में इस मुद्दे को पुन: पेश नहीं कर सकता। मुझे लगता है कि यह मेरे डेटा और आंकड़ों पर निर्भर करता है। ऑप्टिमाइज़र काफी जटिल मॉड्यूल है और कभी-कभी यह जादुई व्यवहार करता है।

यही कारण है कि हम सामान्य रूप से इस प्रश्न का उत्तर नहीं दे सकते क्योंकि यह डीबी इंटर्नल्स पर निर्भर करता है। लेकिन हमें पता होना चाहिए कि उत्तर में ' कोई अंतर नहीं ' होना चाहिए ।


0

मेरे पास आज का यह अनुभव था कि जब उत्पादन में हमारे एसपी के समय का निरीक्षण किया गया था, तो एक एक्सएमएल फीड से निर्मित मेज पर एक आंतरिक जोड़ को बदलकर 'जहां' क्लॉज के बजाय .... औसत निष्पादन समय अब ​​1000 से अधिक निष्पादन में 80 मी है, जबकि औसत निष्पादन से पहले 2.2 सेकंड था ... निष्पादन योजना में प्रमुख अंतर एक महत्वपूर्ण खोज का प्रसार है ... संदेश आपको तब तक पता नहीं चलेगा जब तक कि आप दोनों तरीकों का उपयोग करके परीक्षण नहीं करते।

खुश होती है।



0

जैसा कि केविक ने कहा, निष्पादन योजना समान है।

JOIN स्टेटमेंट केवल पढ़ना अधिक आसान है, जिससे ON कंडीशन को भूलकर कार्टेसियन प्रोडक्ट प्राप्त करना आसान नहीं है। कई प्रकारों के प्रकारों का उपयोग करके लंबे प्रश्नों का पता लगाने में ये त्रुटियां काफी कठिन हो सकती हैं: चयन करें * FROM t1, t2 WHERE t1.id = t2.some_field से।

यदि आप केवल एक जुड़ने की स्थिति को भूल जाते हैं, तो आपको क्वेरी को निष्पादित करने के लिए बहुत लंबा समय मिलता है बहुत सारे रिकॉर्ड ... वास्तव में बहुत सारे। कुछ कवच क्वेरी को पैच करने के लिए एक DISTINCT का उपयोग करते हैं, लेकिन इसे निष्पादित करने के लिए अभी भी बहुत लंबा है।

यही कारण है कि, जॉय कथन का उपयोग करना निश्चित रूप से सबसे अच्छा अभ्यास है: एक बेहतर रखरखाव, और बेहतर पठनीयता।

इसके अलावा, अगर मुझे अच्छी तरह से याद है, तो JOIN मेमोरी उपयोग के विषय में अनुकूलित है।


0

मेरे पास उस अच्छे उत्तर के लिए एक अतिरिक्त है :

यही क्रमशः SQL92 और SQL89 के रूप में परिभाषित किया गया है, उनके बीच कोई प्रदर्शन अंतर नहीं है, हालांकि आप INNER शब्द को छोड़ सकते हैं (बस JOIN का उपयोग पर्याप्त है और सरलतम क्वेरी में आप 5 कीबोर्ड स्ट्रोक बचाते हैं अब कल्पना करें कि कितने स्ट्रोक हैं बड़े में वाले)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.