क्या एक बड़ी क्वेरी को कई छोटे प्रश्नों में अलग करना बेहतर है?


13

ऐसी परिस्थितियां हैं जिनके लिए वांछित परिणामों का उत्पादन करने के लिए उप-चयन कथनों के साथ कई तालिकाओं को मिलाकर वास्तव में बड़ी क्वेरी की आवश्यकता होती है।

मेरा प्रश्न यह है कि, क्या हमें कई छोटे प्रश्नों का उपयोग करने पर विचार करना चाहिए और डीबी को एक से अधिक कॉल में क्वेरी करके तार्किक संचालन को अनुप्रयोग परत में लाना चाहिए या उन सभी को एक बार में लेना बेहतर है?
उदाहरण के लिए निम्नलिखित प्रश्न पर विचार करें:

SELECT *
FROM   `users`
WHERE  `user_id` IN (SELECT f2.`friend_user_id`
                     FROM   `friends` AS f1
                            INNER JOIN `friends` AS f2
                              ON f1.`friend_user_id` = f2.`user_id`
                     WHERE  f2.`is_page` = 0
                            AND f1.`user_id` = "%1$d"
                            AND f2.`friend_user_id` != "%1$d"
                            AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
                                                            FROM   `friends`
                                                            WHERE  `user_id` = "%1$d"))
       AND `user_id` NOT IN (SELECT `user_id`
                             FROM   `friend_requests`
                             WHERE  `friend_user_id` = "%1$d")
       AND `user_image` IS NOT NULL
ORDER  BY RAND() 
LIMIT %2$d

इसे करने का सबसे अच्छा तरीका क्या है?

जवाबों:


14

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

रखरखाव समस्याएं, IME, तब आती हैं जब SQL की संरचना टूट जाती है। सबसेलेक्ट्स में लंबे, जटिल प्रश्नों को पठनीयता और समस्या निवारण के रूप में देखा जाता है, जैसा कि इनलाइन विचार हैं, और इन दोनों को लंबे प्रश्नों से बचा जाना चाहिए। इसके बजाय, यदि आप कर सकते हैं तो VIEW का उपयोग करें (ध्यान दें कि यदि आप MySQL पर हैं, तो दृश्य वे सभी अच्छे प्रदर्शन नहीं करते हैं, लेकिन अधिकांश अन्य db वे करते हैं), और सामान्य तालिका अभिव्यक्तियों का उपयोग करते हैं जहां वे काम नहीं करते हैं (MySQL इनका समर्थन नहीं करता है Btw)।

लंबे समय तक जटिल प्रश्न एक स्थिरता और प्रदर्शन के मामले से बहुत अच्छी तरह से काम करते हैं, जहाँ आप अपने जहाँ को सरल रखते हैं, और जहाँ आप उप-नक्षत्रों के बजाय जोड़ के साथ जितना कर सकते हैं, करते हैं। लक्ष्य यह है कि ऐसा करना ताकि "रिकॉर्ड दिखाई नहीं दे रहे हैं" आपको क्वेरी में कुछ विशिष्ट स्थानों की जांच करने के लिए देता है (क्या यह एक जॉइन में गिराया जा रहा है या एक क्लॉज में फ़िल्टर किया गया है?) और इसलिए रखरखाव टीम वास्तव में चीजों को बनाए रख सकते हैं।

स्केलेबिलिटी के बारे में, ध्यान रखें कि प्लानर के पास जितना अधिक लचीलापन होगा, वह अच्छी बात भी है ...।

संपादित करें: आपने यह उल्लेख किया है कि यह MySQL है, इसलिए इस दृश्य के प्रदर्शन की संभावना नहीं है और CTE के प्रश्न से बाहर हैं। इसके अतिरिक्त दिया गया उदाहरण विशेष रूप से लंबा या जटिल नहीं है ताकि कोई समस्या न हो।


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

8

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

अपने अनुसरण करने वाले लोगों पर जीवन को आसान बनाएं, और वे आपके बारे में अच्छी बातें कहेंगे। उन पर कड़ी मेहनत करो और वे तुम्हें शाप देंगे।


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

मेरे मामले में केवल डीबी का प्रबंधन करना है और कोड स्वयं है। और ज्यादातर मेरा सवाल प्रदर्शन बिंदु क्वेरी के बारे में था।
हमीनी

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

5

2 कीवर्ड क्वेरी-प्रदर्शन और मापनीयता पर मेरे 2 सेंट:

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

स्केलेबिलिटी: प्रश्नों को पढ़ना आसान हो सकता है क्योंकि डेटागोड ने कहा है, और इसे अलग-अलग प्रश्नों में विभाजित करने से समझ में आता है कि क्या आप अपने नए प्रश्नों का उपयोग अन्य क्षेत्रों में भी कर सकते हैं, लेकिन यदि आप उन्हें अन्य कॉल के लिए भी उपयोग नहीं करने जा रहे हैं, तो यह 1 कार्य के लिए प्रबंधित करने के लिए और भी अधिक संग्रहीत प्रोक्स होगा, और IMO स्केलेबिलिटी में कोई योगदान नहीं करेगा।


2
रे: "SQL सर्वर" संदर्भ हालांकि ओपी ने किसी विशेष RDBMS को निर्दिष्ट नहीं किया है, मुझे संदेह है कि वे MySQL पर पिछले टिक से हैं औरLIMIT
मार्टिन स्मिथ

@MartinSmith आपको सही तरीके से संदेह है। यह MySQL है।
ममेनी

2

कुछ समय में, बड़ी / जटिल क्वेरी को छोटे प्रश्नों में विभाजित करने के अलावा कोई विकल्प नहीं होता है। यह निर्धारित करने का सबसे अच्छा तरीका है कि EXPLAINकथन के साथ कथन का उपयोग किया जाए SELECT। आपके डेटा को लाने के लिए आपका db जो निशान / स्कैन करता है, वह आपकी EXPLAINक्वेरी में दिए गए "पंक्तियों" मूल्यों का उत्पाद है । हमारे मामले में, हमारे पास 10 तालिकाओं से जुड़ने की एक क्वेरी थी। विशेष रिकॉर्ड के लिए, ट्रेस 409M है जो हमारे DB को ब्लॉग करता है और हमारे DB सर्वर के CPU उपयोग को 300% से अधिक करता है। हम प्रश्नों को बहुत तेजी से विभाजित करके एक ही जानकारी प्राप्त करने में सक्षम थे।

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

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