2011-09-24 21 views
9

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

विचारों, बहुत सरल हैं सिर्फ चुनिंदा बयान (इन तालिकाओं उन में कुछ लाख पंक्तियाँ होती हैं)। उदाहरण के लिए कहें इस प्रश्न:

SELECT CAST(classifier_results.msgDate as DATE) AS mdate 
     ,classifier_results.objClass AS objClass 
     ,COUNT(classifier_results.objClass) AS obj 
     ,classifier_results.subjClass AS subjClass 
     ,COUNT(classifier_results.subjClass) AS subj 
FROM classifier_results 
WHERE (classifier_results.msgDate >= (curdate() - 20)) 
GROUP BY 
    CAST(classifier_results.msgDate as DATE) 
    ,classifier_results.objClass 
    ,classifier_results.subjClass 
ORDER BY classifier_results.msgDate DESC 

जब सामान्य चयन के रूप में चलाया जाता है तो परिणाम लौटने के लिए लगभग 1.5 सेकंड लगते हैं।

लेकिन जब इस क्वेरी के लिए एक दृश्य में डाल दिया है (के रूप में) - अर्थात

CREATE VIEW V1a_sentiment_AI_current AS  
SELECT CAST(classifier_results.msgDate as DATE) AS mdate 
     ,classifier_results.objClass AS objClass 
     ,COUNT(classifier_results.objClass) AS obj 
     ,classifier_results.subjClass AS subjClass 
     ,COUNT(classifier_results.subjClass) AS subj 
FROM classifier_results 
WHERE (classifier_results.msgDate >= (curdate() - 20)) 
GROUP BY 
    CAST(classifier_results.msgDate as DATE) 
    ,classifier_results.objClass 
    ,classifier_results.subjClass 
ORDER BY classifier_results.msgDate DESC 

क्वेरी के बारे में 10 बार लंबे समय तक (22-30 सेकंड) लेता है। इसलिए मैं सोच रहा हूं कि कुछ अनुकूलन या क्वेरी कैशिंग है जो दृश्यों के साथ काम नहीं करती है या शायद कुछ सेटिंग है जिसे हमने MySQL कॉन्फ़िगरेशन में याद किया है। लेकिन क्या इस दृष्टिकोण को तेज करने का कोई तरीका है, इसलिए यह इस प्रश्न के लिए सिर्फ एक अच्छा प्लेसहोल्डर है?

चल रहा दो प्रश्नों पर व्याख्या: सामान्य चयन देता है:

1, सरल, classifier_results, सभी, idx_date,,,, 594,845, जहां का उपयोग करना; अस्थायी का उपयोग करना; filesort

का उपयोग करते हुए दृश्य का चयन देता है:

1, प्राथमिक, सभी,,,,, 100,
2, व्युत्पन्न, classifier_results, सभी, idx_date,,,, 594,845, का उपयोग करते हुए कहा पे; अस्थायी का उपयोग करना; filesort का उपयोग

+0

यदि आप दोनों क्वेरी के लिए EXPLAIN का उपयोग करते हैं और दृश्य से चयन करते हैं, तो क्या आपको अलग-अलग परिणाम मिलते हैं? – Cocowalla

+0

प्रश्न में जोड़ा गया। क्वेरी प्लान वही दिखता है, मुझे लगता है कि वें ईप्रिमरी सिर्फ दृश्य से वापसी है क्योंकि यह किसी अर्थ में घिरा हुआ है, कुछ भी नहीं जो 20 सेकंड्स + को इंगित करने के लिए अतिरिक्त इंगित करेगा .... – NightWolf

+1

मुझे लगता है कि 'डेरिवेड' का अर्थ है कि यह अस्थायी उपयोग कर रहा है तालिका, जो प्रदर्शन को मार रही है – Cocowalla

उत्तर

0

कोशिश आपका दृश्य का उपयोग कर फिर से बनाने: MySQL के दृश्य प्रसंस्करण एल्गोरिदम पर

CREATE ALGORITHM = MERGE VIEW `V1a_sentiment_AI_current` AS  
SELECT CAST(classifier_results.msgDate as DATE) AS mdate 
    ,classifier_results.objClass AS objClass 
    ,COUNT(classifier_results.objClass) AS obj 
    ,classifier_results.subjClass AS subjClass 
    ,COUNT(classifier_results.subjClass) AS subj 
FROM classifier_results 
WHERE (classifier_results.msgDate >= (curdate() - 20)) 
GROUP BY 
    CAST(classifier_results.msgDate as DATE) 
    ,classifier_results.objClass 
    ,classifier_results.subjClass 
ORDER BY classifier_results.msgDate DESC 

अधिक जानकारी पाया जा सकता है।

+0

ठीक है धन्यवाद इस लिंक के लिए। विचार पहले उल्लिखित था। एमईजीईई में अलगो बदलने की कोशिश करके: 0 पंक्तियां प्रभावित हुईं, 1 चेतावनी: 1354 देखें मर्ज एल्गोरिदम का उपयोग अभी यहां नहीं किया जा सकता है (माना गया अपरिभाषित एल्गोरिदम)। टेम्पलेट अलगो के साथ दृश्य बनाने का प्रयास ठीक काम करता है। तो अनुमान लगाया गया है कि यह TempTable का उपयोग कर सकता है क्योंकि अपरिभाषित विलय और मोहक के बीच एक विकल्प बनाने लगता है। तो यह समस्या हो सकती है, क्योंकि मैनुअल का कहना है कि विलय अधिक कुशल है ... – NightWolf

+0

दृश्य से 'ORDER BY' खंड को हटाने का प्रयास करें और देखें कि यह' MERGE' एल्गोरिदम – Cocowalla

+0

के साथ काम करेगा या नहीं, 'ORDER BY' को अभी भी हटा रहा है विलय के रूप में काम नहीं करना चाहता। '1354 देखें मर्ज एल्गोरिदम का उपयोग अभी के लिए नहीं किया जा सकता है (माना गया अपरिभाषित एल्गोरिदम)' – NightWolf

0

चयन सूची में गिनती() समेकन के कारण मेर्ज का उपयोग यहां नहीं किया जा सकता है; यह इन मामलों में इंजन को उनके बीच निर्णय लेने से बचाने के लिए टेम्पलेट निर्दिष्ट करने में मदद कर सकता है। एक बार जब मैंने तय कर लिया था जो एल्गोरिथ्म का उपयोग मैं समझाता योजना को देखो चाहते हैं और एक सूचकांक संकेत जोड़ने के लिए या एक लापता सूचकांक का पता लगाने की कोशिश करने के लिए।

1

यह एक बहुत आम समस्या है। यह सूखी, फिर से प्रयोग करने योग्य एसक्यूएल लिखने के लिए बहुत मुश्किल हो सकता है। यद्यपि मैंने पाया है कि एक कामकाज है।

सबसे पहले, जैसा कि अन्य ने इंगित किया है, आप सेट ALGORITHM = MERGE का उपयोग करके जहां भी संभव हो वहां ऐसा करने के लिए VIEWs का उपयोग कर सकते हैं और इन्हें उपयोग करने के लिए किसी भी क्वेरी को मर्ज किए गए SQL कथन पर अनुकूलित किया गया है जहां दृश्य देखने के बजाय खंड पूरे दृश्य जो भयंकर बड़ा हो सकता है के लिए मूल्यांकन किया।

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

यह तकनीक आपको पुन: प्रयोज्य प्रश्न लिखने की अनुमति देती है जिसे मिडलवेयर/फ्रेमवर्क कोड से एक्सेस किया जा सकता है और अन्य संग्रहीत प्रक्रियाओं के अंदर से बुलाया जा सकता है, ताकि आप कोड को निहित, रखरखाव और पुन: प्रयोज्य रख सकें।

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

CREATE PROCEDURE sp_create_tmp_V1a_sentiment_AI_current(parm1, parm2 etc) 
BEGIN 

    drop temporary table if exists tmp_V1a_sentiment_AI_current; 

    create temporary table tmp_V1a_sentiment_AI_current 
    as 
    SELECT CAST(classifier_results.msgDate as DATE) AS mdate 
     ,classifier_results.objClass AS objClass 
     ,COUNT(classifier_results.objClass) AS obj 
     ,classifier_results.subjClass AS subjClass 
     ,COUNT(classifier_results.subjClass) AS subj 
    FROM classifier_results 
    WHERE (classifier_results.msgDate >= (curdate() - 20)) 
    -- and/or other filters on parm1, parm2 passed in 
    GROUP BY 
    CAST(classifier_results.msgDate as DATE) 
    ,classifier_results.objClass 
    ,classifier_results.subjClass 
    ORDER BY classifier_results.msgDate DESC; 

END; 

अब, किसी भी समय आप इस डेटा के साथ काम करने की जरूरत है, तो आप प्रक्रिया कॉल और फिर या तो परिणाम का चयन करें या किसी अन्य क्वेरी में इसके साथ शामिल होने के (अतिरिक्त जहां खंड मानकों के साथ संभवतः)।

तालिका एक सत्र अस्थायी तालिका है, इसलिए यह प्रक्रिया से कॉल से परे बनी रहेगी। कॉलिंग कोड या तो डेटा के साथ समाप्त होने के बाद इसे छोड़ सकता है या जब सत्र जाता है या स्पोक को बाद में कॉल किया जाता है तो यह स्वचालित रूप से चला जाएगा।

आशा है कि यह सहायक है।

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