2012-12-31 15 views
5

मेरे पास यह जटिल क्वेरी है जो लगभग 50ms में 3744 पंक्तियां उत्पन्न करती है।MYSQL क्वेरी धीमा - उप क्वेरी और टेम्प तालिका

SELECT 
    srl.event_id as eid 
, srl.race_num as rnum 
, bts.boat_id as bid_id 
, srl.series_year as yr 
, srl.id as id 
, IFNULL(rfi.fleet,fleet_def) as flt_old,flt_match,s.series_id as sid 
, s.series_year as syr 
    ,IFNULL(ovr_pts,POINTS('4',IFNULL(ovr_place,place),num_start)) as points 

FROM 

(SELECT en1.boat_id,en1.boat_name,MAX(fleet) as fleet_def FROM entries en1 
JOIN series_race_list srl1 ON srl1.event_id=en1.event_id 
       AND srl1.series_year=en1.race_year 
LEFT JOIN entries_race er1 ON en1.boat_id= er1.boat_id 
          AND srl1.event_id=en1.event_id  
          AND srl1.series_year =en1.race_year 
WHERE srl1.series_id ='3' AND srl1.series_year ='2012' 
          AND en1.entry_deleted='N'  
GROUP BY boat_id) bts 

JOIN series_race_list srl LEFT JOIN series as s ON s.series_id=srl.series_id 
AND s.series_year =srl.series_year 

LEFT JOIN entries as en ON srl.event_id=en.event_id 
    AND srl.series_year =en.race_year AND bts.boat_id =en.boat_id 

LEFT JOIN entries_race er ON er.race_id= srl.event_id AND er.race_num=srl.race_num 
         AND er.yr = srl.series_year AND bts.boat_id =er.boat_id 

LEFT JOIN event_race_info as eri ON eri.race_id= srl.event_id 
    AND eri.race_num=srl.race_num AND eri.yr = srl.series_year 
    ANd er.line=eri.line  AND status REGEXP 'prelim|final' 

LEFT JOIN race_results as rr ON srl.event_id=rr.race_id 
    AND srl.race_num= rr.race_num AND srl.series_year =rr.yr 
    AND bts.boat_id= rr.boat_id AND checked_in='Y' 

LEFT JOIN race_fleet_info as rfi ON rfi.race_id= srl.event_id 
    AND rfi.yr=srl.series_year AND srl.race_num= rfi.race_num 
    AND rfi.fleet=rr.flt AND complete='Y' 

LEFT JOIN series_pts_override as spo ON srl.id =spo.id AND en.boat_id =spo.bid 

WHERE s.series_id ='3' AND s.series_year ='2012' AND approved ='Y' 

लंबाई के लिए क्षमा करें। जैसा कि मैंने कहा था कि यह क्वेरी लगभग 50ms में निष्पादित होती है। अब मैं इस डेटा का उपयोग करना चाहता हूं और इस 3744 पंक्ति परिणाम पर प्रश्न पूछना चाहता हूं। जैसे ही मैं इसे

SELECT eid FROM(
    ......previous query here..... 
     ) data 

निष्पादन का समय 50 एमएस से 2.5 सेकेंड तक चला जाता है!

मैंने एक अस्थायी तालिका बनाने की कोशिश की, वह वही था। (वास्तव में यह मेरा पसंदीदा दृष्टिकोण है क्योंकि मुझे इस परिणाम सेट पर कुछ अलग-अलग प्रश्नों की आवश्यकता होगी।

इस साइट पर पढ़ना मुझे नहीं लगता कि यह एक सहसंबंधित उप क्वेरी है लेकिन ऐसा लगता है कि यह एक जैसा काम करता है।

, बनाने का कार्य एक उर्फ ​​तालिका मेरी मुद्दों है की तरह लगता है के बाद से उप क्वेरी एक व्युत्पन्न तालिका उपनाम है और अस्थायी तालिका स्पष्ट रूप से एक टेबल है।

मैं डेटा के इन 3744 पंक्तियों पर कैसे पहुँच सकते हैं इस बार जुर्माना के साथ?

यदि यह मदद करेगा तो मैं समझ सकता हूं कि स्पष्टीकरण कैसे पोस्ट करें।

अब क्वेरी के लिए के बारे में बताएं:

id  select_type table  type possible_keys    key  key_len ref             rows Extra 
1  PRIMARY  <derived2> ALL  NULL      NULL  NULL  NULL             3744 
2  DERIVED  s   const PRIMARY      PRIMARY 5                1 
2  DERIVED  srl   ref  series_id,series_id_2  series_id 5                16  Using where 
2  DERIVED  <derived3> ALL  NULL      NULL  NULL  NULL             208  Using join buffer 
2  DERIVED  en   eq_ref PRIMARY,event_id,event_id_2 PRIMARY 9  race_reg_test.srl.event_id,bts.boat_id    1  Using index 
2  DERIVED  er   ref  PRIMARY,boat_id,boat_id_2 boat_id_2 5  bts.boat_id           5 
2  DERIVED  eri   eq_ref PRIMARY      PRIMARY 13  race_reg_test.srl.event_id,race_reg_test.srl.race_... 1 
2  DERIVED  rr   ref  PRIMARY,boat_id    boat_id 4  bts.boat_id           9 
2  DERIVED  rfi   eq_ref PRIMARY      PRIMARY 31  race_reg_test.srl.event_id,race_reg_test.srl.race_... 1 
2  DERIVED  spo   ref  PRIMARY      PRIMARY 8  race_reg_test.srl.id,race_reg_test.en.boat_id   1 
3  DERIVED  srl1  ref  series_id,series_id_2  series_id 5                16  Using index; Using temporary; Using filesort 
3  DERIVED  en1   ref  PRIMARY,event_id,event_id_2 PRIMARY 5  race_reg_test.srl1.event_id       11  Using where 
3  DERIVED  er1   ref  boat_id,boat_id_2   boat_id 4  race_reg_test.en1.boat_id        9  Using index 
+0

अच्छी तरह से नई जानकारी। मुझे लगता है कि निष्पादन के समय केवल चयन के लिए फर्जी हैं। अधिक दिखने वाला और ऐसा लगता है कि चयन में फ़ंक्शन कॉल प्रमुख समय मुद्दा है। अभी भी नहीं पता क्यों phpmyAdmin इस तरह के अलग निष्पादन समय जवाब देता है। हमम ... – davewhirlwind

+0

कोई भी संभावना है कि आप इस डेटासेट में से कुछ को एक दृश्य के साथ encapsulate कर सकते हैं? –

+0

मैं बेस कैश फ्लैग को चालू करने की कोशिश करता हूं: SQL_NO_CACHE srl.event_id चुनें ... बस यह सुनिश्चित करने के लिए कि यह वास्तव में 50ms में वापस आ रहा है और यह कैश से वापस नहीं आ रहा है। – Seth

उत्तर

0

आपने कहा कि आप अस्थायी तालिका बनाने की कोशिश की है, अगर है कि द्वारा आप एक दृश्य मतलब है या नहीं मुझे यकीन है कि नहीं हूँ।

मैं उस क्वेरी के साथ एक व्यू तैयार करूंगा और फिर दृश्य पर आवश्यक कोई भी प्रश्न निष्पादित करूंगा।

CREATE VIEW massive_query_view AS 
SELECT 
    srl.event_id as eid 
, srl.race_num as rnum 
, bts.boat_id as bid_id 
, srl.series_year as yr 
, srl.id as id 
, IFNULL(rfi.fleet,fleet_def) as flt_old,flt_match,s.series_id as sid 
, s.series_year as syr 
    ,IFNULL(ovr_pts,POINTS('4',IFNULL(ovr_place,place),num_start)) as points 

FROM 

(SELECT en1.boat_id,en1.boat_name,MAX(fleet) as fleet_def FROM entries en1 
JOIN series_race_list srl1 ON srl1.event_id=en1.event_id 
       AND srl1.series_year=en1.race_year 
LEFT JOIN entries_race er1 ON en1.boat_id= er1.boat_id 
          AND srl1.event_id=en1.event_id  
          AND srl1.series_year =en1.race_year 
WHERE srl1.series_id ='3' AND srl1.series_year ='2012' 
          AND en1.entry_deleted='N'  
GROUP BY boat_id) bts 

JOIN series_race_list srl LEFT JOIN series as s ON s.series_id=srl.series_id 
AND s.series_year =srl.series_year 

LEFT JOIN entries as en ON srl.event_id=en.event_id 
    AND srl.series_year =en.race_year AND bts.boat_id =en.boat_id 

LEFT JOIN entries_race er ON er.race_id= srl.event_id AND er.race_num=srl.race_num 
         AND er.yr = srl.series_year AND bts.boat_id =er.boat_id 

LEFT JOIN event_race_info as eri ON eri.race_id= srl.event_id 
    AND eri.race_num=srl.race_num AND eri.yr = srl.series_year 
    ANd er.line=eri.line  AND status REGEXP 'prelim|final' 

LEFT JOIN race_results as rr ON srl.event_id=rr.race_id 
    AND srl.race_num= rr.race_num AND srl.series_year =rr.yr 
    AND bts.boat_id= rr.boat_id AND checked_in='Y' 

LEFT JOIN race_fleet_info as rfi ON rfi.race_id= srl.event_id 
    AND rfi.yr=srl.series_year AND srl.race_num= rfi.race_num 
    AND rfi.fleet=rr.flt AND complete='Y' 

LEFT JOIN series_pts_override as spo ON srl.id =spo.id AND en.boat_id =spo.bid 

WHERE s.series_id ='3' AND s.series_year ='2012' AND approved ='Y' 

फिर, आप दृश्य पर क्वेरी कर सकते हैं।

SELECT * FROM massive_query_view; 

आशा है कि चीजों को गति दें। एक और चीज जो आप कर सकते हैं वह है अपनी इंडेक्स की जांच करें। इंडेक्स बनाते हैं जहां क्लोज़ तेजी से होते हैं लेकिन धीमे होते हैं। अधिक जानकारी के लिए, माईएसQL दस्तावेज देखें कि MySQL इंडेक्स का उपयोग कैसे करता है: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

0

कुछ बातें हैं, लेकिन सबसे बड़ी एक मैं देख रहा हूँ आपकी मूल क्वेरी में है ... की

boat_id बिंदु पर) बीटीएस शामिल हों series_race_list SRL बायाँ शामिल हों श्रृंखला है

के रूप में आपके पास कोई बीटीएस और एसआरएल के बीच "चालू" स्थिति जिसके परिणामस्वरूप कार्टेसियन परिणाम और शायद आपके लिए एक बड़ा हत्यारा होगा। बीटीएस में प्रत्येक रिकॉर्ड के लिए, यह एसआरएल में एक प्रविष्टि बना रहा है, फिर उस उत्पाद से श्रृंखला में शामिल हो रहा है। Srl से श्रृंखला तक ठीक है क्योंकि यह स्पष्ट मान्य मानदंड/कुंजी पर शामिल हो गया है।

अगला, आपके पास कुछ फ़ील्ड हैं जो उपनाम नहीं हैं। फ़ील्ड, जैसे अधिकतम (बेड़े) आंतरिक-अधिकांश क्वेरी में जो "बीटीएस" से बाहर निकलती है। इसके अलावा, क्यों MAX (बेड़े) को नाव आईडी द्वारा समूहित किया गया है जिसे मैं प्राथमिक कुंजी के रूप में समझूंगा और अद्वितीय होगा ... क्या एक नाव कभी भी अपने बेड़े को बदल देगा? यदि हां, तो क्या यह सही है? यदि आपके पास बेड़े की एक टेबल है (इसकी अपनी ऑटो-अनुक्रम आईडी भी है), और एक नाव स्वामित्व/प्रायोजक जहाज (जो कुछ भी) से पहले से मौजूद बेड़े में बदलती है ... बेड़े 93 को एक नए व्यक्ति के पास पहले से ही एक आईडी है 47 की फाइल पर जहां 47 सबसे नया रिश्ते था, लेकिन पुराना पूर्व-मौजूदा आईडी ...क्या आप वास्तव में यही चाहते हैं? मैक्स()?

कोई alias.field के लिए अतिरिक्त फील्डः ovr_pts और ovr_place, क्षेत्र सूची में जगह (और क्या अंक() फ़ंक्शन ... status नियमित अभिव्यक्ति पर, दौड़ परिणाम पर checked_in, और दौड़ बेड़े की जानकारी पर पूरा हो गया है , और आखिर में अंतिम जहां खंड में अनुमोदित किया गया। माइनर, लेकिन इंडेक्स अनुकूलन के लिए सहायक हो सकता है।

आखिरकार, आपकी क्वेरी में "s.series_id ... और s.series_year ..." पर WHERE क्लॉज है आपके पास क्वेरी में पहले बाएं-जॉइन है। यह मूल रूप से बाएं-शामिल घटक को रद्द कर देता है और इसे एक अंतर्निहित INNER जॉइन में बदल देता है क्योंकि आप समावेशन के वैध विकल्प के रूप में NULL के लिए अनुमति नहीं दे रहे हैं।

कुछ स्पष्टीकरण के बाद, मैं कुछ के आसपास की क्वेरी को बदलने का भी सुझाव दे सकता हूं, लेकिन सबसे बड़ी बात जो मैंने देखी थी वह शुरुआत से थी ... कोई "चालू" शर्त बीटीएस और श्रृंखला_rate_list तालिका में शामिल नहीं है।

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