एकाधिक प्रश्नों बनाम प्रश्नों को शामिल करें


180

क्या JOIN कई प्रश्नों की तुलना में तेज़ होते हैं? (आप अपनी मुख्य क्वेरी चलाते हैं, और फिर आप अपनी मुख्य क्वेरी से परिणामों के आधार पर कई अन्य चयन चलाते हैं)

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

यदि वे तेज़ हैं, तो क्या कोई भी लगभग कितना मोटे तौर पर लगभग अनुमान लगा सकता है? अगर यह 1.5x है, तो मुझे परवाह नहीं है, लेकिन अगर यह 10x है तो मुझे लगता है कि मैं करता हूं।


मुझे लगता है वे तेज हो जाएगा। मुझे पता है कि 10 व्यक्तिगत INSERT प्रश्नों की तुलना में एक INSERT बहुत तेज है।
एलेक्स

1
यह महत्वपूर्ण हो सकता है कि क्या आपके कई प्रश्न एक संग्रहीत प्रक्रिया के अंदर हैं यदि वे अनुप्रयोग से उत्पन्न होते हैं (इस जानकारी के साथ अपने प्रश्न को संपादित करें)। पूर्व की तुलना में बहुत जल्दी हो जाएगा।
कोलाई लिथियम

जवाबों:


82

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


2
यदि आप अलग-अलग चाबियों पर 3 या अधिक तालिकाओं में शामिल हो रहे हैं, तो अक्सर डेटाबेस (यानी mysql) केवल प्रति तालिका एक सूचकांक का उपयोग कर सकते हैं, जिसका अर्थ है कि शायद एक जोड़ तेजी से (और एक सूचकांक का उपयोग करेगा) जबकि अन्य बहुत धीमी गति से होंगे। कई क्वेरी के लिए, आप प्रत्येक क्वेरी के लिए उपयोग करने के लिए अनुक्रमणिका को अनुकूलित कर सकते हैं।
उपयोगकर्ता 151975

4
मुझे लगता है कि यह आपकी "तेज" की परिभाषा पर निर्भर करता है ... उदाहरण के लिए, 3 पीके इनर जॉइंट नेटवर्क ओवरहेड की वजह से 4 राउंड-ट्रिप से अधिक तेजी से घूम सकते हैं, और क्योंकि आपको प्रत्येक क्वेरी के बाद रुकने और तैयार करने और भेजने की आवश्यकता होती है। पिछली क्वेरी पूरी हो गई है। यदि आप लोड के तहत एक सर्वर को बेंचमार्क करने के लिए थे, हालांकि, ज्यादातर मामलों में, जेके अधिक पीके समय बनाम पीके प्रश्नों को ले जाएगा, और अक्सर अधिक नेटवर्क ओवरहेड का भी कारण बनता है।
mindplay.dk

97

आंतरिक जोड़ के लिए, एक एकल क्वेरी समझ में आता है, क्योंकि आपको केवल मिलान पंक्तियाँ मिलती हैं। बाएं जोड़ों के लिए, कई प्रश्न बहुत बेहतर हैं ... निम्नलिखित बेंचमार्क पर नज़र डालें जो मैंने किया था:

  1. 5 जॉइन के साथ सिंगल क्वेरी

    क्वेरी: 8.074508 सेकंड

    परिणाम का आकार: 2268000

  2. एक पंक्ति में 5 प्रश्न

    संयुक्त क्वेरी समय: 0.00262 सेकंड

    परिणाम का आकार: 165 (6 + 50 + 7 + 12 + 90)

ध्यान दें कि हम दोनों मामलों में समान परिणाम प्राप्त करते हैं (6 x 50 x 7 x 12 x 90 = 2268000)

बाएं जोड़ बेमानी डेटा के साथ तेजी से अधिक मेमोरी का उपयोग करते हैं।

यदि आप केवल दो तालिकाओं में शामिल होते हैं, लेकिन आमतौर पर तीन या अधिक हैं, तो यह मेमोरी लिमिट उतनी बुरी नहीं हो सकती है और यह विभिन्न प्रश्नों के लायक हो जाती है।

एक साइड नोट के रूप में, मेरा MySQL सर्वर मेरे एप्लिकेशन सर्वर के पास सही है ... इसलिए कनेक्शन समय नगण्य है। यदि आपका कनेक्शन समय सेकंड में है, तो शायद एक लाभ है

फ्रैंक


31
यदि हम कष्टप्रद छोटे तथ्य को टॉस करते हैं कि उनके दाहिने दिमाग में कोई भी क्रॉस 5 तालिकाओं के बीच में नहीं जुड़ता है (उस कारण से, इसके साथ ही ज्यादातर मामलों में इसका कोई मतलब नहीं है ), आपके "बेंचमार्क" में कुछ योग्यता हो सकती है । लेकिन बाएं या भीतरी जोड़ आदर्श हैं, आमतौर पर कुंजी द्वारा (पुनर्प्राप्ति को बहुत तेजी से बनाकर), और डेटा का दोहराव आमतौर पर बहुत अधिक होता है, जितना आप इसे बाहर कर रहे हैं उससे बहुत कम है।
cHao

12
@cHao कौन कहता है? मैंने सिर्फ SMF और phpBB को देखा और 3 तालिकाओं के बीच JOIN को देखा - यदि आप प्लगइन्स या संशोधनों को जोड़ते हैं तो वे आसानी से जोड़ सकते हैं। किसी भी तरह के बड़े एप्लिकेशन में कई जॉइन की क्षमता है। संभवतः एक खराब लिखा हुआ / गलत उपयोग किया गया ORM तालिकाओं को जोड़ सकता है कि इसकी वास्तव में आवश्यकता नहीं है (शायद हर तालिका भी)।
नताली एडम्स

5
@ नथन एडम्स: लेफ्ट और इनर जॉइन बिल्कुल भी बुरे नहीं हैं। (वास्तव में, यदि आप यहां और वहां तालिकाओं में शामिल नहीं हो रहे हैं, तो आप SQL गलत कर रहे हैं।) मैं किस बारे में बात कर रहा था क्रॉस जॉइन , जो लगभग हमेशा दो टेबल के बीच भी अवांछनीय हैं, अकेले चलो 5 - और कौन सा अन्यथा उल्लिखित पूरी तरह से फर्जी "2268000" परिणाम प्राप्त करने का एकमात्र तरीका है।
cHao

2
परिणाम देखें, हालांकि। "परिणाम का आकार: 2268000" बनाम "परिणाम का आकार: 165"। मुझे लगता है कि JOINs के साथ आपकी मंदी का कारण यह है कि आपके रिकॉर्ड का एक-दूसरे के साथ एक-से-कई संबंध हैं, जबकि अगर उनके बीच एक-से-एक संबंध था, तो JOIN बिल्कुल तेज हो जाएगा और इसका परिणाम निश्चित रूप से नहीं होगा आकार से बड़ा आकार।
होल्डऑफहंगर

3
@ cHao स्पष्ट रूप से आप अपनी पहली टिप्पणी के समय मैगेंटो से नहीं मिले हैं
vitoriodachef

26

यह प्रश्न पुराना है, लेकिन कुछ मानदंड गायब हैं। मैंने इसके 2 प्रतियोगियों के खिलाफ JOIN बेंच दिया:

  • एन + 1 प्रश्न
  • 2 प्रश्न, एक WHERE IN(...)या समकक्ष का उपयोग करने वाला दूसरा

परिणाम स्पष्ट है: MySQL पर, JOINहै बहुत तेजी से। N + 1 क्वेरी किसी एप्लिकेशन के प्रदर्शन को अत्यधिक गिरा सकती है:

जहां बनाम एन + 1 में शामिल हों

यही है, जब तक कि आप बहुत सारे रिकॉर्ड का चयन नहीं करते हैं जो बहुत कम संख्या में विशिष्ट, विदेशी रिकॉर्ड की ओर इशारा करते हैं। यहाँ चरम मामले के लिए एक बेंचमार्क है:

जॉय बनाम एन + 1 - एक ही विदेशी रिकॉर्ड की ओर इशारा करते हुए सभी रिकॉर्ड

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

ले जाओ:

  • * -To-one संबंधों के लिए, हमेशा उपयोग करें JOIN
  • * -कई रिश्तों के लिए, एक दूसरी क्वेरी अधिक तेज़ हो सकती है

अधिक जानकारी के लिए माध्यम पर मेरा लेख देखें ।


22

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

मैं समझ सकता हूं कि यदि क्वेरी करने का एक तरीका 0.02 सेकंड कहता है और दूसरे को 20 सेकंड लगते हैं, तो यह बहुत बड़ा अंतर है। लेकिन क्या होगा अगर क्वेरी करने का एक तरीका 0.0000000002 सेकंड लेता है, और दूसरा एक 0.0000002 सेकंड लेता है? दोनों ही मामलों में एक तरीका दूसरे की तुलना में 1000 गुना अधिक तेज है, लेकिन क्या यह वास्तव में दूसरे मामले में "मजबूत" है?

निचला रेखा जैसा कि मैं व्यक्तिगत रूप से इसे देखता हूं: यदि यह अच्छा प्रदर्शन करता है, तो आसान समाधान के लिए जाएं।


4
यह, निश्चित रूप से, आप स्केलिंग पर योजना बना रहे हैं या नहीं, इसके आधार पर। Cuz जब facebook ने शुरू किया तो मुझे यकीन है कि उनके पास इस तरह के प्रश्न थे, लेकिन मन में स्केलिंग थी और संभवतः अधिक जटिल समाधान के लिए अधिक कुशल यद्यपि के लिए चला गया।
दूदावद

@dudewad समझ में आता है। यह सब इस बात पर निर्भर करता है कि आपको आखिर में क्या चाहिए।
वैलेंटाइन फ्लैचेल

4
हाहा हाँ ... क्योंकि गूगल पर 1 नैनोसेकंड खोया सचमुच 10 बिलियन ट्रिलियन डॉलर के समान है ... लेकिन यह सिर्फ एक अफवाह है।
ड्यूडवाड

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

15

एक त्वरित परीक्षण 50,000 पंक्ति तालिका से एक पंक्ति का चयन और 100,000 पंक्ति तालिका से एक पंक्ति के साथ जुड़ने का किया। मूल रूप से देखा:

$id = mt_rand(1, 50000);
$row = $db->fetchOne("SELECT * FROM table1 WHERE id = " . $id);
$row = $db->fetchOne("SELECT * FROM table2 WHERE other_id = " . $row['other_id']);

बनाम

$id = mt_rand(1, 50000);
$db->fetchOne("SELECT table1.*, table2.*
    FROM table1
    LEFT JOIN table1.other_id = table2.other_id
    WHERE table1.id = " . $id);

दो चयनित विधि ने 50,000 रीड्स के लिए 3.7 सेकंड का समय लिया जबकि जॉइन ने मेरे घर पर धीमी गति से कंप्यूटर पर 2.0 सेकंड का समय लिया। INNER JOIN और LEFT JOIN में फर्क नहीं किया गया। एकाधिक पंक्तियाँ प्राप्त करना (जैसे, IN SET का उपयोग करके) समान परिणाम मिले।


1
हो सकता है कि अंतर भिन्न हो सकता है यदि पंक्तियों के एक पृष्ठ (जैसे 20 या 50) का चयन करना, जैसे कि एक सामान्य वेब व्यू ग्रिड के लिए, और एकल LEFT JOIN की तुलना दो प्रश्नों के लिए करना - 2 या 3 पहचानकर्ताओं का चयन कुछ WHERE मानदंडों के साथ और फिर दूसरे को चलाना IN () के साथ क्वेरी का चयन करें।
जस्टामार्टिन

क्या कॉलम आईडी और other_id अनुक्रमित हैं?
आरिश रमेश

11

असली सवाल यह है कि क्या इन रिकॉर्डों में एक-से-एक संबंध या एक-से-कई संबंध हैं ?

TLDR उत्तर:

यदि एक-से-एक, एक JOINकथन का उपयोग करें ।

यदि एक-से-कई, SELECTसर्वर-साइड कोड अनुकूलन के साथ एक (या कई) बयानों का उपयोग करें ।

अनुकूलन के लिए चयन क्यों और कैसे करें

SELECTएक से कई संबंधों के आधार पर रिकॉर्ड के बड़े समूह पर 'आईएनजी (जॉइन के बजाय कई प्रश्नों के साथ) एक इष्टतम दक्षता पैदा करता है, क्योंकि JOIN' आईएनजी में एक घातीय मेमोरी लीक मुद्दा है। सभी डेटा को पकड़ो, फिर इसे सॉर्ट करने के लिए सर्वर-साइड स्क्रिप्टिंग भाषा का उपयोग करें:

SELECT * FROM Address WHERE Personid IN(1,2,3);

परिणाम:

Address.id : 1            // First person and their address
Address.Personid : 1
Address.City : "Boston"

Address.id : 2            // First person's second address
Address.Personid : 1
Address.City : "New York"

Address.id : 3            // Second person's address
Address.Personid : 2
Address.City : "Barcelona"

यहाँ, मुझे सारे रिकॉर्ड मिल रहे हैं, एक चुनिंदा स्टेटमेंट में। यह उससे बेहतर है JOIN, जो इन रिकॉर्ड्स का एक छोटा समूह, एक समय में, एक अन्य क्वेरी के उप-घटक के रूप में प्राप्त कर रहा होगा। फिर मैं इसे सर्वर-साइड कोड के साथ पार्स करता हूं जो कुछ इस तरह दिखता है ...

<?php
    foreach($addresses as $address) {
         $persons[$address['Personid']]->Address[] = $address;
    }
?>

जब अनुकूलन के लिए शामिल होने का उपयोग करने के लिए नहीं

JOIN'एक एकल रिकॉर्ड के साथ एक-से-एक संबंध के आधार पर रिकॉर्ड के एक बड़े समूह को सम्मिलित करना, कई SELECTबयानों की तुलना में एक इष्टतम दक्षता पैदा करता है , एक के बाद एक, जो बस अगले रिकॉर्ड प्रकार को प्राप्त करते हैं।

लेकिन JOINएक-से-कई संबंधों के साथ रिकॉर्ड बनाते समय अक्षम है।

उदाहरण: डेटाबेस ब्लॉग में रुचि के 3 टेबल हैं, Blogpost, Tag और Comment।

SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;

यदि 1 ब्लॉगपोस्ट, 2 टैग और 2 टिप्पणियाँ हैं, तो आपको परिणाम मिलेंगे:

Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,

ध्यान दें कि प्रत्येक रिकॉर्ड को कैसे दोहराया जाता है। ठीक है, इसलिए, 2 टिप्पणियाँ और 2 टैग 4 पंक्तियाँ हैं। यदि हमारे पास 4 टिप्पणियाँ और 4 टैग हैं तो क्या होगा? आपको 8 पंक्तियाँ नहीं मिलतीं - आपको 16 पंक्तियाँ मिलती हैं:

Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag1, comment3,
Row4: tag1, comment4,
Row5: tag2, comment1,
Row6: tag2, comment2,
Row7: tag2, comment3,
Row8: tag2, comment4,
Row9: tag3, comment1,
Row10: tag3, comment2,
Row11: tag3, comment3,
Row12: tag3, comment4,
Row13: tag4, comment1,
Row14: tag4, comment2,
Row15: tag4, comment3,
Row16: tag4, comment4,

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

इन डुप्लिकेट्स की क्या कीमत है? मेमोरी (SQL सर्वर में और कोड जो डुप्लिकेट को निकालने की कोशिश करता है) और नेटवर्किंग संसाधन (SQL सर्वर और आपके कोड सर्वर के बीच)।

स्रोत: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html


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

@cHao: आपकी टिप्पणी के लिए धन्यवाद। ऊपर दिया गया मेरा उत्तर MySQL प्रलेखन का सारांश है: dev.mysql.com/doc/workbench/en/wb-relationship-tools.html
HoldOffHunger

यह MySQL प्रलेखन नहीं है। यह MySQL डेटाबेस के साथ काम करने के लिए एक विशेष GUI उपकरण के लिए प्रलेखन है। और यह उचित होने पर किसी भी मार्गदर्शन की पेशकश नहीं करता है (या नहीं) उपयुक्त हैं।
cHao

@cHao: क्षमा करें, मेरा मतलब MySQL WorkBench (TM) के लिए MySQL (R) प्रलेखन था, MySQL Server (TM) नहीं।
होल्डऑफहुंगर

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

8

दोनों अलग-अलग प्रश्नों का निर्माण करते हैं और जुड़ते हैं, फिर उनमें से प्रत्येक समय - वास्तविक दुनिया की संख्या से अधिक कुछ भी मदद नहीं करता है।

फिर और भी बेहतर - प्रत्येक क्वेरी की शुरुआत में "EXPLAIN" जोड़ें। यह आपको बताएगा कि डेटा के लिए आपके अनुरोध का जवाब देने के लिए MySQL कितनी सबक्वेरी का उपयोग कर रहा है, और प्रत्येक क्वेरी के लिए कितनी पंक्तियाँ स्कैन की गई हैं।


7

डेवलपर जटिलता की तुलना में डेटाबेस के लिए जटिलता के आधार पर, कई चयनित कॉल करना सरल हो सकता है।

JOIN और कई SELECTS दोनों के खिलाफ कुछ डेटाबेस आँकड़े चलाने की कोशिश करें। देखें कि क्या आपके वातावरण में JOIN SELECT की तुलना में तेज़ / धीमा है।

तो फिर, अगर इसे एक JOIN में बदलने का मतलब होगा एक अतिरिक्त दिन / सप्ताह / देव कार्य का महीना, तो मैं कई चयनों के साथ रहूँगा

चीयर्स,

बीएलटी


5

अपने अनुभव में मैंने पाया है कि आमतौर पर कई प्रश्नों को चलाना तेजी से होता है, खासकर जब बड़े डेटा सेट को पुनः प्राप्त करना।

किसी अन्य एप्लिकेशन जैसे PHP से डेटाबेस के साथ बातचीत करते समय, सर्वर पर एक यात्रा का तर्क कई पर होता है।

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

जब एसक्यूएल की बात आती है तो मैं कोई नौसिखिया नहीं हूं, मुझे लगता है कि डेवलपर्स के लिए एक प्रवृत्ति है, विशेष रूप से जूनियर्स ने बहुत समय बिताने के लिए बहुत चतुर जोड़ लिखने की कोशिश की है क्योंकि वे स्मार्ट दिखते हैं, जबकि वास्तव में डेटा को निकालने के लिए स्मार्ट तरीके हैं जो देखो सरल।

अंतिम पैराग्राफ एक निजी राय थी, लेकिन मुझे उम्मीद है कि इससे मदद मिलेगी। मैं अन्य लोगों से सहमत हूं, जो कहते हैं कि आपको बेंचमार्क चाहिए। न तो दृष्टिकोण एक चांदी की गोली है।


हां, हमें केवल प्रश्नों के लिए ही नहीं, बल्कि एप्लिकेशन के अंदर डेटा प्रोसेसिंग के लिए भी ध्यान देना चाहिए। यदि बाहरी जोड़ के साथ डेटा लाना, कुछ अतिरेक है (कभी-कभी यह वास्तव में बहुत बड़ा हो सकता है) जिसे ऐप द्वारा सुलझाया जाना है (आमतौर पर कुछ ORM पुस्तकालय में), इस प्रकार सारांश में JOIN क्वेरी के साथ एकल चयन अधिक CPU का उपभोग कर सकता है दो सरल चयनों से अधिक समय
जस्टमार्टिन

4

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

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

ऐसा अक्सर कई रिश्तों के कारण होता है। उदाहरण के लिए, होल्डऑफहुंगर के उत्तर में पोस्ट, टैग और टिप्पणियों के लिए एक ही प्रश्न का उल्लेख किया गया है। टिप्पणियां किसी पोस्ट से संबंधित हैं, जैसे टैग हैं ... लेकिन टैग टिप्पणियों से असंबंधित हैं।

+------------+     +---------+     +---------+
|  comment   |     |   post  |     |  tag    |
|------------|*   1|---------|1   *|---------|
| post_id    |-----| post_id |-----| post_id |
| comment_id |     | ...     |     | tag_id  |
| user_id    |     |         |     | ...     |
| ...        |     |         |     | ...     |
+------------+     +---------+     +---------+

इस मामले में, कम से कम दो अलग-अलग प्रश्नों का होना बेहतर है। यदि आप टैग और टिप्पणियों में शामिल होने का प्रयास करते हैं, क्योंकि दोनों के बीच कोई सीधा संबंध नहीं है, तो आप टैग और टिप्पणी के हर संभव संयोजन के साथ समाप्त होते हैं। many * many == manymany। इसके अलावा, चूंकि पोस्ट और टैग असंबंधित हैं, आप उन दो प्रश्नों को समानांतर में कर सकते हैं, जिससे संभावित लाभ होगा।

चलो एक अलग परिदृश्य पर विचार करते हैं, हालांकि: आप एक पोस्ट से जुड़ी टिप्पणियों और टिप्पणीकारों की संपर्क जानकारी चाहते हैं।

 +----------+     +------------+     +---------+
 |   user   |     |  comment   |     |   post  |
 |----------|1   *|------------|*   1|---------|
 | user_id  |-----| post_id    |-----| post_id |
 | username |     | user_id    |     | ...     |
 | ...      |     | ...        |     +---------+
 +----------+     +------------+

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


यदि आप दूसरे परिदृश्य में बहुत सारे उपयोगकर्ता कॉलम पुनः प्राप्त करते हैं (और वही उपयोगकर्ता एक से अधिक बार टिप्पणी करते हैं), तो यह अभी भी यह प्रश्न छोड़ देता है कि क्या वे एक अलग क्वेरी में सर्वश्रेष्ठ पुनर्प्राप्त किए गए हैं।
एड्रियन बेकर

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

वे दोनों अनुकूलन कम करने या अतिरेक को समाप्त करने के लिए एक जुड़ाव के साथ अद्भुत काम कर सकते हैं, लेकिन बहुत कुछ ऐसा नहीं है जो संबंधित धारावाहिक प्रश्नों के साथ मदद कर सकता है जो आपको संबंधित रिकॉर्ड प्राप्त करने के लिए करना होगा।
cHao

3

क्या यह थ्रूपुट के मामले में तेज होगा? शायद। लेकिन यह संभावित रूप से एक समय में अधिक डेटाबेस ऑब्जेक्ट्स (आपके डेटाबेस और आपके स्कीमा पर निर्भर करता है) को लॉक कर देता है और जिससे समवर्ती घट जाती है। मेरे अनुभव में लोग अक्सर "कम डेटाबेस राउंड-ट्रिप" तर्क से गुमराह होते हैं जब वास्तविकता में अधिकांश ओएलटीपी सिस्टम पर जहां डेटाबेस एक ही लैन पर होता है, वास्तविक अड़चन शायद ही कभी नेटवर्क होती है।


2

यहां 100 उपयोगी प्रश्नों के साथ एक लिंक दिया गया है, इन्हें Oracle डेटाबेस में परीक्षण किया गया है लेकिन याद रखें कि SQL एक मानक है, जो Oracle, MS SQL Server, MySQL और अन्य डेटाबेस के बीच भिन्न है, SQL बोली है:

http://javaforlearn.com/100-sql-queries-learn/


1

कई कारक हैं जिनका अर्थ है कि कोई द्विआधारी उत्तर नहीं है। प्रदर्शन के लिए सबसे अच्छा सवाल आपके पर्यावरण पर निर्भर करता है। वैसे, यदि एक पहचानकर्ता के साथ आपका एकल चयन उप-सेकंड नहीं है, तो आपके कॉन्फ़िगरेशन में कुछ गलत हो सकता है।

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

जॉइन एक ही बार में सभी डेटा को पुनः प्राप्त करेगा। यदि आप एक रिपोर्ट उत्पन्न कर रहे हैं या एक ग्रिड को आबाद कर रहे हैं, तो यह वही हो सकता है जो आप चाहते हैं। संकलित और ऑप्टोमाइज्ड जोड़ इस परिदृश्य में एकल चयनों की तुलना में अधिक तेज़ होते हैं। याद रखें, ऐड-हॉक जॉइन्स उतने तेज नहीं हो सकते हैं - आपको उन्हें (एक संग्रहीत खरीद में) संकलित करना चाहिए। गति का उत्तर निष्पादन योजना पर निर्भर करता है, जो यह बताता है कि डेटा पुनर्प्राप्त करने के लिए DBMS क्या कदम उठाता है।


0

हां, JOINS का उपयोग करने वाली एक क्वेरी जल्दी होगी। यद्यपि आपके द्वारा क्वेरी किए जा रहे तालिकाओं के संबंधों को जाने बिना, आपके डेटासेट का आकार, या जहां प्राथमिक कुंजी हैं, यह कहना लगभग असंभव है कि कितना तेज है।

क्यों न दोनों परिदृश्यों का परीक्षण किया जाए, तब आपको पता चलेगा ...

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