2016-05-04 6 views
6
OS=centos 6.7 [Dedicated server] 
memory=15G  
cpu=Intel(R) Xeon(R) CPU E5-2403 
mysql= V 5.1.73  

यहां एक MyISAM तालिका है और इसमें डेटा की लगभग 5 मिलियन पंक्तियां हैं। लगभग 3000 उपयोगकर्ताओं के लिए प्रत्येक 5-6 मिनट के डेटा में डेटा डाला जाता है (उदा। अपलोड और डाउनलोड दर, सत्र स्थिति आदि)।बड़े मायिसम टेबल के लिए MySQL अनुकूलन

टेबल जानकारी: वर्णन "radacct"

enter image description here

my.cnf

enter image description here

enter image description here

क्वेरी की mysql धीमी क्वेरी लॉग एक जो सबसे अधिक समय लेता है से

से नीचे है
Query_time: 7.941773 Lock_time: 0.155912 Rows_sent: 1 Rows_examined: 5377 
use freeradius; 
SET timestamp=1461582118; 
SELECT sum(acctinputoctets) as upload, 
     sum(acctoutputoctets) as  download 
    FROM radacct a 
    INNER JOIN (SELECT acctuniqueid, MIN(radacctid)  radacctid 
        FROM radacct 
        WHERE username='batman215' 
        and acctstarttime between '2016-02-03 12:10:47' 
              and '2016-04-25 16:46:01' 
        GROUP BY acctuniqueid) b 
     ON a.acctuniqueid = b.acctuniqueid 
     AND a.radacctid = b.radacctid; 

समझाने क्वेरी उत्पादन

enter image description here

कई उपयोगकर्ताओं को जो अपने भस्म बैंडविड्थ को देखने के लिए सर्वर उच्च लोड और आईओ की वजह से अनुरोध पूरा नहीं कर सकता की कोशिश कर रहे हैं जब। क्या कोई चीज है जो मैं डेटाबेस को अनुकूलित करने के लिए कर सकता हूं? तालिका "radacct" से

इंडेक्स

enter image description here

\ जी

enter image description here

ठनक यू का उपयोग किए बिना क्वेरी के बारे में बताएं

+1

क्या आपके अनुक्रमित हैं दिखाते हैं और आपको कृपया उत्पादन समझाने क्षैतिज पोस्ट कर सकते हैं (आसान तुलना करने के लिए) – e4c5

+0

भी अपने सूचकांक दिखा। –

+0

आप उपयोगकर्ता नाम और एक्टटास्टटाइम फ़ील्ड पर एक बहु कॉलम अनुक्रमणिका जोड़ने का प्रयास कर सकते हैं। – Shadow

उत्तर

7

के इस बाहर अपने भीतर क्वेरी, के साथ शुरू काम करते हैं जो है:

 SELECT acctuniqueid, 
       MIN(radacctid) radacctid 
      FROM radacct 
     WHERE username='batman215' 
      and acctstarttime between '2016-02-03 12:10:47' 
           and '2016-04-25 16:46:01' 
     GROUP BY acctuniqueid 

आप username पर एक समानता मैच की तलाश कर रहे हैं और acctstarttime पर एक श्रेणी मिलान की तलाश में हैं। इसके बाद आप समूह के लिए acctuniqueid उपयोग कर रहे हैं और radacctid से एक चरम मूल्य (MIN()) खींच रहा है।

इसलिए, इस सबक्वायरी को तेज़ करने के लिए, आपको निम्न यौगिक अनुक्रमणिका की आवश्यकता है।

(username, acctstarttime, acctuniqueid, radacctid) 

यह कैसे काम करता है? एक सूचकांक के बारे में सोचें (ये बीटीई इंडेक्स हैं) इसमें मूल्यों की एक क्रमबद्ध सूची के रूप में।

  1. क्वेरी इंजन सूची यादृच्छिक तक पहुँचता है - तेजी से, हे (लॉग (एन)) - पहली प्रविष्टि username मिलान और अपने BETWEEN श्रेणी के कम अंत खोजने के लिए।
  2. यह अनुक्रमिक रूप से सूची को स्कैन करता है, प्रवेश द्वारा प्रविष्टि, जब तक यह BETWEEN सीमा के उच्च अंत तक नहीं आता है। इसे इंडेक्स रेंज स्कैन कहा जाता है।
  3. यह स्कैन किए जाने पर, यह क्रम में acctuniqueid, के प्रत्येक नए मूल्य के लिए लग रहा है और उसके बाद सबसे कम मूल्य लेता है - क्रम में पहले एक - radacctid की, तो accuniqueid के अगले मूल्य के लिए आगे को छोड़ देता है।इसे ढीला इंडेक्स स्कैन कहा जाता है और यह चमत्कारिक रूप से सस्ता है।

तो, कि यौगिक सूचकांक जोड़ें। इससे शायद आपके क्वेरी प्रदर्शन में बड़ा अंतर आएगा।

आपका बाहरी क्वेरी इस तरह दिखता है।

SELECT sum(acctinputoctets) as upload, 
     sum(acctoutputoctets) as  download 
    FROM radacct a 
INNER JOIN ( /*an aggregate 
       * yielding acctuniqueid and raddactid 
       * naturally ordered on those two columns 
       */ 
      ) b ON a.acctuniqueid = b.acctuniqueid 
       AND a.radacctid =  b.radacctid 

इसके लिए आपको यौगिक को कवर सूचकांक

(acctuniqueid, radacctid, acctinputoctets, acctoutputoctets) 

जरूरत क्वेरी के इस भाग को भी सूचकांक जादू से संतुष्ट है।

  1. इंडेक्स में पहले दो कॉलम आंतरिक क्वेरी के परिणाम के आधार पर आपको आवश्यक प्रत्येक पंक्ति के लुकअप की अनुमति देते हैं।
  2. क्वेरी इंजन फिर अन्य दो कॉलम मानों को जोड़कर इंडेक्स स्कैन कर सकता है।

(यह एक कवर सूचकांक कहा जाता है, क्योंकि यह कुछ स्तंभ है कि वर्तमान सिर्फ इसलिए कि हम उनके मूल्यों चाहते हैं, इसलिए नहीं कि हम चाहते हैं उन्हें अनुक्रमित होते हैं। कुछ अन्य बनाता है और DBMS के मॉडल अतिरिक्त कॉलम शामिल करने की अनुमति इंडेक्स में उन्हें खोजे बिना। यह थोड़ा सस्ता है, खासकर INSERT संचालन पर। MySQL ऐसा नहीं करता है।)

तो, आपका पहला कार्य आइटम: इन दो यौगिक अनुक्रमणिका जोड़ें और अपनी क्वेरी को पुनः प्रयास करें।

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

तीसरा, इस http://use-the-index-luke.com/ यह बहुत उपयोगी है पढ़ा जाना।

प्रो टिप: क्या आपने देखा कि मैंने आपकी क्वेरी को कैसे स्वरूपित किया? एक व्यक्तिगत स्वरूपण सम्मेलन का विकास करना जो स्पष्ट रूप से तालिकाओं, कॉलम, ON स्थितियों को दिखाता है, और एक प्रश्न के अन्य पहलुओं को जरूरी है जब आपको एक को समझना होगा।

+0

आपके सर्वर को इस एप्लिकेशन के लिए पर्याप्त रूप से प्रावधान किया गया है। यह एल्गोरिदम (इंडेक्स) का एक मामला है जो ब्रूट फायरपावर की तुलना में बड़ा अंतर बनाता है। –

+0

एकल कॉलम इंडेक्स वहां हैं ताकि 'उपयोगकर्ता नाम का चयन करें, framedipaddress, radacct से servicetype जहां उपयोगकर्ता नाम =' batman215 'इसका उपयोग कर सकता है, तो मुझे सही करें। धन्यवाद, मैंने आपके द्वारा दिए गए समय और मूल्यवान अंतर्दृष्टि की सराहना की। –

+1

'उपयोगकर्ता नाम' से शुरू होने वाला एक कंपाउंड इंडेक्स आपके ऊपर उल्लिखित क्वेरी को भी तेज़ करेगा। –

0
   WHERE username='batman215' 
       and acctstarttime between ... 

इसी क्रम में INDEX(username, acctstarttime) के लिए भीख माँगता।

ON a.acctuniqueid = b.acctuniqueid 
    AND a.radacctid = b.radacctid; 

INDEX(acctuniqueid, radacctid) के लिए भीख माँगता (या तो क्रम में) (या ओली के कवर इंडेक्स)।

"3000 के बारे में उपयोगकर्ताओं के लिए हर 5-6 मिनट के डेटा में डाला जाता है" के बजाय InnoDB MyISAM के लिए भीख माँगता। MyISAM टेबल ताले करता है, जिससे 'सम्मिलित' अन्य प्रश्नों के साथ हस्तक्षेप करता है। Conversion tips

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