2012-01-18 14 views
5

मान लीजिए आप इस तरह एक प्रश्न है ...व्युत्पन्न तालिका पर अनुक्रमणिका का उपयोग करने के लिए मैं MySQL ऑप्टिमाइज़र को कैसे बताऊं?

SELECT T.TaskID, T.TaskName, TAU.AssignedUsers 
FROM `tasks` T 
    LEFT OUTER JOIN (
     SELECT TaskID, GROUP_CONCAT(U.FirstName, ' ', 
      U.LastName SEPARATOR ', ') AS AssignedUsers 
     FROM `tasks_assigned_users` TAU 
      INNER JOIN `users` U ON (TAU.UserID=U.UserID) 
     GROUP BY TaskID 
    ) TAU ON (T.TaskID=TAU.TaskID) 

एकाधिक लोगों को एक दिए गए कार्य को सौंपा जा सकता। इस क्वेरी के प्रयोजन के कार्य प्रति एक पंक्ति को दिखाने के लिए है, लेकिन लोगों को एक एकल स्तंभ

अब में काम करने के लिए आवंटित साथ ... मान लीजिए आप tasks, users, और tasks_assigned_users पर उचित अनुक्रमणिका सेटअप। व्युत्पन्न तालिका में tasks में शामिल होने पर MySQL ऑप्टिमाइज़र अभी भी TaskID अनुक्रमणिका का उपयोग नहीं करेगा। WTF?!?!?

तो, मेरा सवाल है ... आप इस क्वेरी को functions_assigned_users पर इंडेक्स का उपयोग कैसे कर सकते हैं। TaskID? अस्थायी सारणी लंगड़े हैं, इसलिए यदि यह एकमात्र समाधान है ... MySQL ऑप्टिमाइज़र बेवकूफ है।

इंडेक्स का इस्तेमाल किया:

  • कार्यों
    • प्राथमिक - TaskID
  • उपयोगकर्ताओं
    • प्राथमिक - UserID
  • tasks_assigned_users
    • प्राथमिक - (TaskID, UserID)
    • अतिरिक्त सूचकांक अद्वितीय - (UserID, TaskID)

संपादित करें: इसके अलावा, this page का कहना है कि व्युत्पन्न टेबल क्रियान्वित कर रहे हैं/materialized से पहले होने मिलती है । शामिल होने के लिए चाबियों का दोबारा उपयोग क्यों न करें?

संपादित करें 2: यहाँ इस बारे में वास्तव में अच्छा ब्लॉग पोस्ट है: MySQL अनुकूलक आप व्युत्पन्न टेबल पर index hints डाल

संपादित 3 (संभवतः क्योंकि वहाँ व्युत्पन्न टेबल पर कोई अनुक्रमणिका कर रहे हैं) नहीं दूँगा : http://venublog.com/2010/03/06/how-to-improve-subqueries-derived-tables-performance/ ध्यान दें कि केस # 2 वह समाधान है जिसे मैं ढूंढ रहा हूं, लेकिन ऐसा लगता है कि MySQL इस समय इसका समर्थन नहीं करता है। :(

संपादित करें 4: बस this पाया: "MySQL 5.6.3 के रूप में, अनुकूलक और अधिक कुशलता से FROM खंड (अर्थात, व्युत्पन्न टेबल) में सबक्वेरी संभालती है: ... क्वेरी निष्पादन के दौरान, अनुकूलक यह से पंक्ति पुनर्प्राप्ति तेजी लाने के लिए एक व्युत्पन्न मेज पर एक सूचकांक जोड़ सकते हैं। "होनहार लगता है ...

+0

क्या आप जिन इंडेक्स का उपयोग कर रहे हैं उन्हें भी जोड़ सकते हैं? मुझे लगता है कि आपके पास कार्यों पर एक पीके है और task_assigned_users पर एक गैर-अद्वितीय अनुक्रमणिका है। – Luis

+0

@Luis - आपके लिए प्रश्न संपादित किया गया :) – BMiner

+0

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

उत्तर

4

वहाँ MySQL सर्वर 5.6 में इस के लिए एक समाधान है - (इस लेखन के समय) पूर्वावलोकन रिलीज़ ।

http://dev.mysql.com/doc/refman/5.6/en/from-clause-subquery-optimization.html

हालांकि, मैं अगर MySQL अनुकूलक जाएगा फिर से उपयोग अनुक्रमित है कि पहले से ही मौजूद है जब यह

"व्युत्पन्न मेज पर अनुक्रमित कहते हैं," यकीन नहीं है निम्न क्वेरी पर विचार करें:

चुनें * टीसे जुड़ें (चयन करें * टी 2 से) AS derived_t2 t1.f1 = derived_t2.f1 पर;

प्रलेखन कहता है: "ऑप्टिमाइज़र derived_t2 से कॉलम f1 पर एक इंडेक्स बनाता है यदि ऐसा करने से सबसे कम लागत निष्पादन योजना के लिए रिफ एक्सेस के उपयोग की अनुमति मिल जाएगी।"

ठीक है, यह बढ़िया है, लेकिन क्या ऑप्टिमाइज़र टी 2 से इंडेक्स का पुन: उपयोग करता है? दूसरे शब्दों में, क्या होगा यदि t1.f1 के लिए कोई अनुक्रमणिका मौजूद है? क्या यह अनुक्रमणिका पुन: उपयोग की जाती है, या अनुकूलक व्युत्पन्न तालिका के लिए इस अनुक्रमणिका को पुन: उत्पन्न करता है? कौन जानता है?

संपादित करें: MySQL 5.6 तक का सबसे अच्छा समाधान एक अस्थायी तालिका बनाना है, उस तालिका पर एक अनुक्रमणिका बनाएं, और फिर temp तालिका पर SELECT क्वेरी चलाएं।

+1

मारियाडीबी 10 (साल बाद) पर एक ही बेवकूफ स्थिति: भले ही समूह द्वारा व्युत्पन्न किया गया है, फिर भी स्पष्ट सॉर्टिंग के कारण क्वेरी (हास्यास्पद चयन v1 से v1 से v1) को तेज करता है, सबसे अच्छा परिणाम यह है कि यदि आप पहले से सभी व्युत्पन्न टेबल बनाते हैं मुख्य प्रश्न और स्पष्ट रूप से आवश्यक इंडेक्स जोड़ें। अनुकूलक sux – Tertium

1

मैं कर रहा हूँ डर है, यह not possible है। तुम एक अस्थायी तालिका या एक सूचकांक का उपयोग करने के एक दृश्य बनाना होगा।

+0

वह पोस्ट 2006 से है। तब से कोई बदलाव नहीं आया है? – BMiner

+0

मुझे दो कारणों से ऐसा नहीं लगता है। 1) यह MySQL है। 2) उदाहरण के लिए 2010 से इस समस्या के बारे में अन्य पोस्ट हैं (http://planet.mysql.com/entry/?id=23769)। बीटीडब्ल्यू, क्या आप एक दृश्य का उपयोग कर सकते हैं? – AndreKR

+0

मुझे पता नहीं है ... मैंने पढ़ा है कि विचारों में समान समस्याएं हैं, लेकिन मैं इसे अभी आज़मा दूंगा ... – BMiner

2

समस्या मुझे दिखाई देती है कि एक सबक्वायरी करके कोई अंतर्निहित अनुक्रमित तालिका नहीं है। आप एक प्रदर्शन मैं कुछ इस तरह अंत में समूहीकरण चाहते हैं, कर रहे हैं:

SELECT T.TaskID, T.TaskName, GROUP_CONCAT(U.FirstName, ' ', U.LastName SEPARATOR ', ') AS AssignedUsers 
FROM `tasks` T 
    LEFT OUTER JOIN `tasks_assigned_users` TAU ON (T.TaskID=TAU.TaskID) 
    INNER JOIN `users` U ON (TAU.UserID=U.UserID) 
GROUP BY T.TaskID, T.TaskName 
+0

यह काम करता है ... लेकिन चूंकि यह एक ही परिणाम है, मुझे नहीं पता कि MySQL मेरे लिए यह अनुकूलन क्यों नहीं कर सकता है। इसके अलावा, मेरे * वास्तविक * क्वेरी में लगभग 20 कॉलम हैं; मुझे MySQL को उन सभी को समूहित करना होगा? मैं * वास्तव में * केवल टास्किड को समूहबद्ध करना चाहता हूं, टास्किड और टास्कनाम नहीं ... MySQL दोनों कॉलम द्वारा समूहित करते समय अतिरिक्त कार्य करता है। हां पता है मेरा क्या मतलब है? – BMiner

+0

बताए और कहने की कोशिश न करें; यदि उनकी आवश्यकता है, तो उन्हें एक घोषणा नहीं करना एक त्रुटि है ताकि आप आसानी से महसूस कर सकें (मुझे नहीं पता कि उनकी आवश्यकता है या नहीं)।मुझे नहीं पता कि यह अनुकूलन क्यों नहीं कर सकता है; मेरा अनुमान है कि subqueries बाहरी क्वेरी के लिए एक काला बॉक्स हैं, लेकिन मुझे नहीं पता। आम तौर पर मैं इस तरह की प्रदर्शन समस्याओं के कारण subqueries से बचें। – Luis

+0

क्या MySQL इतना समझने के लिए पर्याप्त है कि T.TaskID द्वारा GROUP, T.TaskName T.TaskID द्वारा ग्रुप के समान है क्योंकि T.TaskID प्राथमिक कुंजी है? – BMiner

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

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