तेज प्रश्नों के लिए डुप्लिकेट कॉलम?


30

शीर्षक बहुत ज्यादा मायने नहीं रखता है, लेकिन मैं इस समस्या के लिए एक बेहतर शीर्षक नहीं सोच सकता।

मेरे पास निम्न तालिकाएँ हैं

परियोजनाओं

  • आईडी
  • नाम

ग्राहकों

  • आईडी
  • id_project
  • नाम

भुगतान

  • आईडी
  • id_customer
  • तारीख
  • योग

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

SELECT FROM payments where id_customer in (SELECT id from customers where id_project = 5)

मेरा प्रश्न है: यदि भुगतान तालिका में कॉलम id_project जोड़ना बेहतर नहीं है तो इस तरह से प्रश्न आसान और तेज़ होंगे।


1
इसलिए क्वेरी आधुनिक RDBMSes के लिए एक समस्या नहीं है (या बेहतर, जॉइन यूज़)।
गरिक

4
सहमत हों, सबसिनेट बनाम ज्वाइन के लिए एक क्वेरी प्लान प्राप्त करें और देखें कि कौन सा बेहतर है
गयुस

1
मुझे लगता है कि यह एसओ पोस्ट देखने लायक है, क्योंकि @ जॉय या आईएन का उपयोग करने के बारे में @ जिक्र किया गया है
कोडरवाक

जवाबों:


52

ऐसा लगता है कि आप पूछ रहे हैं कि क्या विकृति समझ में आती है।

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

जवाब हमेशा "यह निर्भर करता है", इसलिए यहां मेरे अंगूठे का नियम है:

अगर ...

  • डेटा की मात्रा बड़ी नहीं है
  • आप पहले से ही एक टन नहीं कर रहे हैं
  • और / या डेटाबेस प्रदर्शन वर्तमान में एक अड़चन नहीं है

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

मैं केवल तभी वश में करूंगा जब ...

  • डेटा की मात्रा बहुत बड़ी है
  • जॉन्स महंगे हैं और तुच्छ प्रश्नों को वापस लाने के लिए आपको उनमें से बहुत कुछ करना होगा
  • डेटाबेस प्रदर्शन एक अड़चन है और / या आप जितनी जल्दी हो सके जाना चाहते हैं

आधुनिक हार्डवेयर में जोड़ बहुत तेज हैं, लेकिन वे कभी भी स्वतंत्र नहीं होते हैं।


9

बेहतर होगा कि आप प्रश्न को फिर से लिखें:

SELECT payments.*
FROM   customers
JOIN   payments 
ON     payments.id_customer = customers.id
WHERE  customers.id_project = 5

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

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

एक साइड नोट के रूप में: स्पष्ट रूप से मुझे आपके व्यवसाय का पता नहीं है इसलिए मुझे कुछ याद आ रहा है, लेकिन आपके टेबल संबंध मुझे अजीब लगते हैं। वे कहते हैं कि आपके पास एक ही ग्राहक के साथ एक से अधिक परियोजना नहीं हो सकती है, जो आमतौर पर मेरे अनुभव में सच नहीं है, कम से कम लंबी अवधि में।

customer     project      payment
--------     --------     -------
                          pa_id
             pr_id    <-- payment
cu_id    <-- customer     

या अगर कम सामान्यीकृत किया जा रहा है (हालांकि मुझे संदेह है कि आवश्यक होगा):

customer     project      payment
--------     --------     --------
                          pa_id
             pr_id    <-- payment
cu_id    <-- customer 
           `------------- customer    

बेशक, अभी भी दो ग्राहकों के साथ एक संयुक्त परियोजना की संभावना को छूट देता है ...


3
प्रदर्शन का पहला नियम: उत्पादन में कभी भी उपयोग न करें *!
ब्रायन बॉल्सन-स्टैंटन

@ ब्रायन: बहुत ही मान्य बिंदु। और साथ ही संभावित प्रदर्शन निहितार्थ * सेलेक्ट क्लॉज में भी परहेज करने से MSSQL में व्यू-ऑन-व्यू में कॉलम ऑर्डरिंग की समस्या से बचा जाता है अगर sys.depends के बजाय DROP VIEW+ के CREATE VIEWबजाय उपयोग किए जाने के कारण किल्टर से बाहर हो जाता है ALTER VIEW
डेविड स्पिललेट

@ ब्रायन मैं * लेखन के लिए आसान है।
गेब्रियल सोलोमन

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

4

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

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