2010-03-13 9 views
9

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

+---------+-----------+---------------+---------------------+---------------------+-----------------+ 
| vehicle | engine | engine_state | state_start_time | state_end_time  | engine_variable | 
+---------+-----------+---------------+---------------------+---------------------+-----------------+ 
| 080025 | E01  | active  | 2008-01-24 16:19:15 | 2008-01-24 16:24:45 |    720 | 
| 080028 | E02  | inactive  | 2008-01-24 16:19:25 | 2008-01-24 16:22:17 |    304 | 
+---------+-----------+---------------+---------------------+---------------------+-----------------+ 

एक विशिष्ट विश्लेषण के लिए, हम सक्रिय/निष्क्रिय इंजन राज्य की वर्तमान आधार मिनट की एक पंक्ति का विवरण स्तर, बजाय के आधार पर तालिका सामग्री का विश्लेषण करना चाहते हैं। इसके लिए, हम प्रत्येक अवधि में दिनांक-समय कॉलम पर productionMinute और engineEvent तालिकाओं का विश्लेषण कर रहे हैं और प्रत्येक अवधि के लिए एक पंक्ति के साथ एक सरल productionMinute तालिका बनाने की सोच रहे हैं। इसलिए यदि हमारी अवधि की अवधि 2009-12-01 से 2010-02-28 तक है, तो हम 12 9,600 पंक्तियों के साथ एक नई तालिका तैयार करेंगे, जो कि तीन महीने की अवधि के लिए प्रत्येक दिन के प्रत्येक मिनट के लिए एक होगी। productionMinute तालिका की पहली कुछ पंक्तियाँ:

+---------------------+ 
| production_minute | 
+---------------------+ 
| 2009-12-01 00:00 | 
| 2009-12-01 00:01 | 
| 2009-12-01 00:02 |  
| 2009-12-01 00:03 | 
+---------------------+ 

तालिकाओं के बीच में शामिल होने के होगा:

  1. engineState:

     FROM engineState AS es 
    LEFT JOIN productionMinute AS pm ON pm.production_minute >= es.state_start_time 
               AND pm.production_minute <= es.event_end_time 
    

    यह शामिल होने हालांकि, कई पर्यावरण के मुद्दों लाता है तालिका में 5 मिलियन पंक्तियां हैं और productionMinute तालिका में 130,000 पंक्तियां हैं

  2. जब engineState पंक्ति एक से अधिक मिनट तक फैलती है (यानी। es.state_start_time और es.state_end_time के बीच का अंतर, एक मिनट से अधिक) है उदाहरण में मामला ऊपर है, कई productionMinute तालिका पंक्तियों है कि एक ही engineState तालिका पंक्ति में शामिल हो रहे हैं
  3. जब कोई दौरान आपरेशन में एक से अधिक इंजन है दिए गए मिनट, यह भी ऊपर के उदाहरण के अनुसार, कई engineState तालिका पंक्तियों एक भी productionMinute पंक्ति

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

कई लोगों के साथ तालिकाओं में शामिल होने के लिए सबसे अच्छा क्वेरी डिज़ाइन क्या है: उपरोक्त उल्लिखित भविष्यवाणी के बीच कई रिश्ते क्या हैं? सबसे अच्छा शामिल प्रकार क्या है (बाएं/दाएं, भीतरी)?

+0

एक ठोस उदाहरण है कि आप किस प्रकार की रिपोर्ट जेनरेट करने की कोशिश कर रहे हैं, इससे मदद मिलेगी। यह काफी संभव है कि आपको प्रति मिनट अवलोकन में विस्तार करने की आवश्यकता नहीं है और सीधे आपके परिणाम बना सकते हैं। साथ ही, आपके इंजनस्टेट टेबल पर आपके पास कौन से इंडेक्स हैं? – Martin

+0

आपकी शिकायत संख्या 2 और 3 पर्यावरणीय मुद्दे नहीं हैं, वे डिजाइन मुद्दे हैं। मेरा मतलब यह है कि मैं उनमें से किसी के साथ कुछ भी गलत नहीं देख सकता - वे सच हैं क्योंकि आपने अपना डेटा इस तरह से रखा है। आपको यह वर्णन करने की आवश्यकता है कि आप इसे एक समस्या के रूप में क्यों देखते हैं और यह स्पष्ट करते हैं कि आपने जो भी लिखा है उससे आप क्या उम्मीद करते हैं (आप इसका अर्थपूर्ण अर्थ क्या करेंगे: डी)। – Unreason

उत्तर

0

प्रदर्शन इस बात पर निर्भर करेगा कि टेबल में आपका डेटा किस प्रकार संरचित है।

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

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

+0

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

+0

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

+0

रिपोस्ट जेरेमी के लिए धन्यवाद। मेरा मानना ​​है कि MySQL हमें नियोजित करने के लिए इंडेक्स प्रकार निर्दिष्ट करने की अनुमति देता है। हम इस विकल्प को और देखेंगे, जिसे हम पाते हैं उस पर वापस पोस्ट करेंगे। – lighthouse65

1

डाटा पुनर्प्राप्ति प्रदर्शन डिस्क पर डेटा तक पहुँच की

  • गति के समारोह है
  • (अनुक्रमित के अस्तित्व, टेबल के आकार, कैश का आकार, कच्चे आई/ओ गति पर निर्भर करता है)
  • रिकॉर्ड लौटे होने की जरूरत है कि की संख्या
  • (कुछ पंक्तियों की संख्या दी को कम करने, कुछ वृद्धि, कुछ स्थितियों अनुक्रमित पर लागू किया जा सकता कुछ रिकॉर्ड के पास जाना चाहिए मिलती है)
  • कॉलम कि आप

वापस जाने के लिए इन सब के लिए जरूरत की संख्या आप

  • जोड़ने अनुक्रमित
  • यह खड़ी विभाजन के आधार पर तालिका के आकार को कम अनुकूलन कर सकते हैं (में तालिका बंटवारे दो या दो से अधिक अर्थात् अलग-अलग तालिकाओं - उदाहरण के लिए यदि आपकी 5 एम तालिका से आप वास्तव में 100k रिकॉर्ड्स के साथ काम करते हैं तो 99.5% समय हो सकता है कि आप तालिका को सक्रिय/निष्क्रिय या समान में विभाजित कर सकते हैं)
  • प्रदान करना जो आप विभाजित नहीं कर सकते लंबवत रूप से आप क्षैतिज रूप से एक तालिका विभाजित कर सकते हैं - तालिकाओं की संख्या भी पुनर्प्राप्ति गति को प्रभावित करती है (लेकिन उतनी अधिक नहीं)
  • अंत में कच्चे I/O गति में सुधार करने से तालिका को कई हार्ड डिस्क में पारदर्शी रूप से विभाजित करके प्राप्त किया जा सकता है (लेकिन पता है आपके मौलिक फाइल सिस्टम गुण)

इंडेक्स के प्रदर्शन पर उच्चतम प्रभाव है क्योंकि वे परिमाण के आदेश द्वारा स्मृति कार्यों में डिस्क उपयोग समय और गति में कटौती कर सकते हैं ((एन वे हे बारी) हे (एन) लॉग इन करना होगा सूचकांक संरचना रखरखाव की लागत पर; इसलिए वे अद्यतन धीमा कर देते हैं)

अधिकतम पुनर्प्राप्ति गति सूचकांक के लिए सभी शामिल होना चाहिए और कहां स्थितियों और प्रश्नों को इस तरह लिखा जाना चाहिए कि क्वेरी ऑप्टिमाइज़र यह निर्धारित कर सके कि इनमें से कौन सा सबसे पहले लाभ उठाएगा (उच्चतम चयनात्मकता)।

अपने विशेष उदाहरण के लिए अनुक्रमित

का बेंचमार्क विभिन्न संयोजन करने की कोशिश
  1. pm.production_minute es.state_start_time साथ के लिए यकीन है कि
  2. अनुक्रमित किया जाना चाहिए और es.state_end_time आप 4 संभव सूचकांक विकल्प हैं (जो आप कर सकते हैं es.state_start_time
    सूचकांक पर
    सूचकांक es.state_end_time
    सूचकांक पर (es.state_start_time, es.state_end_time) (es.state_end_time पर
    सूचकांक पर: गठबंधन) , es.state_start_time)

आपके डेटा को जानना आपको यह निर्धारित करने देगा कि कौन सा इष्टतम है। अगर आपको पता चलेगा कि पिछले दो दो कॉलम इंडेक्स सर्वश्रेष्ठ प्रदर्शन करेंगे तो मुझे आश्चर्य नहीं होगा। या एक सिंगल कॉलम और एक और दो कॉलम इंडेक्स (लेकिन कॉलम के विपरीत क्रम में)।

इन मामलों सभ्य अनुकूलक सिर्फ अनुक्रमित पढ़ने और यहां तक ​​कि वास्तविक रिकॉर्ड को देखकर नहीं से resultset निर्धारित करने के लिए सक्षम हो जाएगा के दोनों और उस में काफी हद तक आपके डिस्क पहुँच कटौती।

0

मेरा अनुभव यह है कि MySQL क्वेरी ऑप्टिमाइज़र बहुत खराब है। PostgreSQL में से एक बहुत बेहतर है।

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

1

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

आप अपनी समस्या लगता है के माध्यम से आप बस अपने डेटा denormalizing रहे हैं और किराए की कुंजी के रूप में मिनट क्रमांक देने हैं। यह एक अपेक्षाकृत आसान (और सामान्य) ईटीएल समस्या है जो सीधे एसक्यूएल में निष्पादक नहीं है लेकिन अन्य भाषाओं और उपकरणों के साथ सरल है।

आपका उत्पादन की मात्रा को आसानी से एक सच्चे ETL प्रक्रिया के द्वारा नियंत्रित किया जाएगा।

0

अगर मैं सही ढंग से समझ में आया, आप एक बीआई समस्या में देख रहे हैं। एक बीआई लेआउट ऑपरेटिव डेटा समेकित एक के अलावा होगा।

इसके लिए (त्वरित और गंदी) आप तीन तत्वों की आवश्यकता होगी तो होना।

  • आपका ऑपरेटिव डेटा
  • एक ETL काम है, जो केवल क्वेरी आप दिखाया है प्रदर्शन और
  • Denormalized टेबल जहाँ आप अपने consilidated डेटा बचा सकते हैं एक और denormalized तालिका में resultset सम्मिलित करना होता है।

इस तरह आप अपनी क्वेरी को तेज करेंगे क्योंकि यह अब एक साधारण चयन होगा।

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

दूसरी तरफ, आप बीआई तरीके को बंद कर सकते हैं और अपनी वर्तमान स्कीमा/क्वेरी पर काम कर सकते हैं। आप इंडेक्स, आंकड़े जोड़ सकते हैं, टेबल बदल सकते हैं लेकिन मेरी राय में यह एक स्केलेबल समाधान नहीं है। आप तीन महीने के डेटाबेस के लिए प्रदर्शन समस्या को हल कर सकते हैं, लेकिन यदि आपके पास तीन साल का डेटाबेस है तो क्या होगा?

0

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

आम तौर पर, इनर जॉइन बहुत अनुकूलक अनुकूल होते हैं, क्योंकि इससे आपके WHERE क्लॉज से अलग फ़िल्टर मानदंडों की अनुमति मिलती है और जॉइन स्थिति को इंडेक्स स्कैन या टेबल स्कैन में सुधार करने के लिए बहुत अधिक धक्का दिया जाता है। रेफरेंशियल अखंडता बाधाएं दोनों तरफ मौजूद होने वाले डेटा के बारे में ऑप्टिमाइज़र जानकारी भी दे सकती हैं।

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

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

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

संबंधित मुद्दे