2010-06-28 17 views
5

निम्न क्वेरी काम करती है, लेकिन 10 रिकॉर्ड्स (2 सेकंड) के लिए यह बहुत धीमी है। प्रोफाइलिंग का कहना है कि यह एक टीएमपी टेबल बना रहा है, लेकिन मुझे यकीन नहीं है कि क्यों।MySQL - यह क्वेरी कैसे अनुकूलित की जा सकती है?

असल में, मैं वर्तमान उपयोगकर्ता, एसीएल समूहों में शामिल हो रहा हूं, उन सभी समूहों को प्राप्त करने के लिए, फिर समूह में कंपनियों से जुड़ना, उन सभी कंपनियों को प्राप्त करने के लिए, फिर कंपनियों को आदेश में शामिल करना , सभी आदेशों पाने के लिए ..

अगर मैं इस लाइन

ORDER BY orders.created_on DESC 

फिर क्वेरी 0.06 सेकेंड में कार्यान्वित (अधिक स्वीकार्य तो) ..

सहायता, अनुकूलन के लिए पर किसी भी विचार को दूर ? बहुत धन्यवाद :)

SELECT 
    orders.uuid, 
    companies.name as company_name 
FROM 
    users u 
JOIN  
    users_acl_groups g on u.uuid = g.user_uuid 
JOIN 
    users_acl acl on (acl.user_uuid = u.uuid or acl.group_uuid = g.group_uuid) 
JOIN 
    companies on acl.item_uuid = companies.uuid 
JOIN 
    orders on companies.uuid = orders.company_uuid 
WHERE 
    u.uuid = 'DDEC8073-5056-C000-01ED583A51CBCA32' and orders.status <> '' 
ORDER BY orders.created_on DESC 

limit 0, 10; 

अद्यतन, .. क्वेरी के समझाने

1 सरल आदेश सभी 9403 अस्थायी का उपयोग करना; फाइलों का उपयोग

1 सिंपल एसीएल सभी 1859 कहां उपयोग करना; बफर

1 सिंपल जी सभी 2005 का उपयोग करके; का उपयोग बफर

1 सरल कंपनियों eq_ref प्राथमिक प्राथमिक 52 table.orders.company_uuid 1

1 सरल यू सभी 33,595 जहां का उपयोग शामिल हो; विशिष्ट; बफर में शामिल होने का उपयोग कर

+0

आपके शीर्षक को संशोधित करते हुए अनुमान लगाया गया है कि यह आपके अनिवार्य और मांगने वाले स्वर के कारण एक डाउनवोट खर्च करता है जब आपका प्रश्न अच्छी तरह से कहा जाता है। –

+0

यूआईडी के अलावा किसी भी कॉलम पर लागू होने के साथ एक ही क्वेरी का उपयोग करने का प्रयास करें। Int, float, string, UID के साथ ऐसा करने का प्रयास करें और समय पर ध्यान दें। अगर आपको कोई बदलाव मिलता है तो हमें यह भी बताएं। –

+0

क्या आपके पास order.created_on पर एक अनुक्रमणिका है? अपनी क्वेरी पर 'EXPLAIN' पर आउटपुट दिखाएं। शायद आप अन्य इंडेक्स से लाभ उठा सकते हैं। कौन सा 'एक्सप्लाइन' हमें बताएगा। – nos

उत्तर

2

आप एक तथ्य तालिका शैली के डिजाइन बनाने एक असमान्यीकरण कदम के रूप में माना जाता है?

मूल रूप से यह कई-से-अनेक चौराहे तालिका का एक प्रकार है, उदाहरण के लिए:

CREATE TABLE user_order_fact (
    user_uuid ... 
    order_uuid ... 
    order_created_on ... 
    order_status ... 
    company_name ..., 
    primary key (user_uuid, order_uuid), 
    key (user_uuid, order_status, order_created_on, order_uuid, company_name) 
); 

... fill with data ... 

SELECT 
    order_uuid, 
    company_name 
FROM 
    user_order_fact 
WHERE 
    user_uuid = 'DDEC8073-5056-C000-01ED583A51CBCA32' and order_status <> '' 
ORDER BY order_created_on DESC 

limit 0, 10; 

मैं यौगिक सूचकांक पर अनुमान लगा रहा हूँ। आपको तब तक प्रयोग करना होगा जब तक आप इसे सही न लें। असल में आप ऑप्टिमाइज़र योजना को रिपोर्ट करने की कोशिश कर रहे हैं कि यह इंडेक्स का उपयोग कर रहा है।

बेशक यह डेटा को अनावश्यक रूप से और denormalized रूप में संग्रहीत कर रहा है, इसलिए आपको इसे सामान्यीकृत तालिकाओं के साथ समन्वयित रखने के लिए कुछ ट्रिगर सेट अप करने की आवश्यकता है।

+0

हम्म शायद पीके सिर्फ order_uuid है। मैं यह गारंटी नहीं दे रहा हूं कि यह सबसे अच्छा डिज़ाइन है, बस आपको इसका मतलब महसूस करने का प्रयास करना है। –

0

सुनिश्चित करें कि "order.created_on" में एक अनुक्रमणिका है ... यदि ऐसा होता है, तो शीर्ष पर बिल का दृष्टिकोण सबसे अच्छा होगा हालांकि कुछ काम की आवश्यकता होगी।

+0

मुझे लगता है कि यह करता है? कुंजी 'बनाया_ऑन' ('बनाया_on') – Brett

0

मौजूदा इंडेक्स या प्रत्येक तालिका की मात्रा के बारे में बहुत कुछ जानने के बिना जवाब देना मुश्किल है।

इसके अलावा, मॉडल के बारे में अधिक जानकारी के बिना ... क्या क्वेरी सभी परिणामों को वापस कर देती है?

क्या सभी उपयोगकर्ता एक समूह के हैं? ऐसा लगता है कि नहीं ... और क्वेरी एक समूह के बाहर उपयोगकर्ताओं को वापस नहीं करेगा।

क्या कोई समूह एक समूह से संबंधित हो सकता है, जो रिकर्सिव क्वेरी के लिए कॉल कर रहा है?

+0

मैं उस रिकर्सिव क्वेरी चीज को काम करने की कोशिश कर रहा था लेकिन मुझे बहुत भाग्य नहीं मिला :(तालिका शांत है, 10,000 रिकॉर्ड सभी हैं। इस समय कोई अनुक्रमणिका नहीं है .. – Brett

+0

@ ब्रेट: इस मामले में मौजूद इंडेक्स काम नहीं करेंगे, क्योंकि ऑपरेटर और ऑपरेटर की तरह इंडेक्स –

0

मुझे यकीन नहीं है कि 2 सेकंड लेने का सटीक कारण क्या हो सकता है। जो इस क्वेरी 10 रिकॉर्ड प्राप्त करने में कठिनाई के लिए संभव नहीं है, लेकिन देखने के लिए यहाँ है क्या

  1. acl.user_uuid = u.uuid or acl.group_uuid = g.group_uuid

    यूआईडी आधारित में शामिल होने हैं, आप भी हैं एक प्राथमिक कुंजी के रूप में उपयोग के रूप में ऊपर दिए हो सकता है।

  2. ORDER BY orders.created_ondate पर उपयोग करना पीके या किसी भी पूर्णांक मान का उपयोग करने से इष्टतम नहीं होगा।

  3. orders.status <> '' हैं क्योंकि नहीं ऑपरेटर और जैसा ऑपरेटर जब किसी भी क्वेरी में उपयोग अनुक्रमित का उपयोग करता है नहीं करता है तो कोई सूचकांक इस क्वेरी में इस्तेमाल किया जा सकता टेबल पर किसी भी अनुक्रमित का उपयोग कर।

  4. किसी तालिका में मौजूद रिकॉर्ड्स का वॉल्यूम एक और कारण हो सकता है लेकिन केवल उपरोक्त कारकों के कारण। अन्यथा यह बड़ी मात्रा में भी संभाला जा सकता था।

प्रमुख कारक योगदान मुझे लगता है कि यूआईडी में इस्तेमाल किया जा रहा शामिल तो तीनों से बचने की स्थिति आपकी क्वेरी में देखा जा सकता है जो आपकी क्वेरी आलसी

+0

हाय का उपयोग नहीं करते हैं, आपके प्रतिक्रियाओं के लिए धन्यवाद .. नंबर 2 में कम से कम क्या मतलब है? – Brett

0

कुछ विचार कर सकता है है:

आप वास्तव में अपनी क्वेरी में orders.created_on का चयन नहीं कर रहे हैं। तो उस कॉलम पर सॉर्ट करने का कोई मतलब नहीं है। शायद, इसे चुनना (SELECT orders.created_on ...) प्रदर्शन में मदद करेगा (बस जंगली अनुमान - मुझे नहीं पता कि मैं यहां क्या बात कर रहा हूं)।

आप हमेशा अपने आवेदन में सॉर्ट कर सकते हैं - यदि आपकी क्वेरी द्वारा रिकॉर्ड की गई बड़ी संख्या में रिकॉर्ड नहीं हैं।

कभी-कभी 1 बड़ी एसक्यूएल क्वेरी के बजाय एन छोटे प्रश्नों का उपयोग करने के लिए यह अधिक प्रदर्शन करने योग्य होता है। छद्म कोड:

user_id = get_one("SELECT uuid FROM users WHERE ..."); 
group_ids = get_many("SELECT uuid FROM groups WHERE user_uuid = " + user_id); 
comps_ids = get_many("SELECT DISTINCT item_uuid FROM acls WHERE user_uuid = " + user_id + " OR group_uuid IN " + groups_ids.to_q()); 
orders = get_many("SELECT * FROM orders WHERE company_uuid IN " + comps_ids.as_q() + " WHERE status <> '' ORDER BY created_on"); 
संबंधित मुद्दे