mysql

2017-09-05 6 views
5

में शामिल होने के साथ प्रदर्शन द्वारा क्रम में सुधार कैसे करें मैं सोशल नेटवर्क ट्रैकिंग एप्लिकेशन पर काम कर रहा हूं। उचित इंडेक्सिंग के साथ भी जुड़ा हुआ काम करता है। लेकिन जब मैं खंड द्वारा ऑर्डर जोड़ता हूं तो कुल क्वेरी निष्पादित करने में 100 गुना अधिक समय लेती है। निम्नलिखित क्वेरी मैं क्लॉज द्वारा आदेश के बिना twitter_users प्राप्त करने के लिए उपयोग किया जाता था।mysql

SELECT DISTINCT `tracked_twitter`.id 
FROM tracked_twitter 
INNER JOIN `twitter_content` ON `tracked_twitter`.`id` = `twitter_content`.`tracked_twitter_id` 
INNER JOIN `tracker_twitter_content` ON `twitter_content`.`id` = `tracker_twitter_content`.`twitter_content_id` 
AND `tracker_twitter_content`.`tracker_id` = '88' 
LIMIT 20 

दिखा पंक्तियों 0 - 19

(कुल 20, क्वेरी 0.0714 सेकंड लिया) लेकिन जब मैं (अनुक्रमित स्तंभ पर) खंड द्वारा आदेश जोड़ने

SELECT DISTINCT `tracked_twitter`.id 
FROM tracked_twitter 
INNER JOIN `twitter_content` ON `tracked_twitter`.`id` = `twitter_content`.`tracked_twitter_id` 
INNER JOIN `tracker_twitter_content` ON `twitter_content`.`id` = `tracker_twitter_content`.`twitter_content_id` 
AND `tracker_twitter_content`.`tracker_id` = '88' 
ORDER BY tracked_twitter.followers_count DESC 
LIMIT 20 

दिखा पंक्तियों 0 - 19 (कुल 20, क्वेरी 13.4636 सेकंड)

व्याख्या enter image description here

ले लिया

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

SELECT * FROM `tracked_twitter` WHERE 1 order by `followers_count` desc limit 20 

दिखा पंक्तियों 0 नहीं ले करता है - 19 (कुल 20, क्वेरी 0.0711 सेकंड लिया) [FOLLOWERS_COUNT: 68236387 - 10525612]

के रूप में तालिका बनाने क्वेरी इस प्रकार

CREATE TABLE IF NOT EXISTS `tracked_twitter` (
    `id` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    `handle` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    `location` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `description` text COLLATE utf8_unicode_ci, 
    `profile_image` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    `followers_count` int(11) NOT NULL, 
    `is_influencer` tinyint(1) NOT NULL DEFAULT '0', 
    `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `gender` enum('Male','Female','Other') COLLATE utf8_unicode_ci 
    DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `followers_count` (`followers_count`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

तो में शामिल होने के साथ-साथ काम करके क्वेरी और व्यवस्था गति कम नहीं हुई है जब मैं अपनी मेज पर अमल। तो मैं प्रदर्शन में सुधार कैसे कर सकता हूं?

अद्यतन 1

@GordonLinoff विधि को हल करती है अगर मैं केवल परिणाम माता पिता मेज से सेट की जरूरत है। मैं प्रति व्यक्ति संख्या ट्वीट्स जानना चाहता हूं (twitter_content की गिनती जो tracked_twitter तालिका से मेल खाती है)। मैं इसे कैसे संशोधित कर सकता हूं? और अगर मैं ट्वीट सामग्री पर गणित कार्य करना चाहता हूं तो मैं इसे कैसे कर सकता हूं ??

SELECT `tracked_twitter` . * , COUNT(*) AS twitterContentCount, retweet_count + favourite_count + reply_count AS engagement 
FROM `tracked_twitter` 
INNER JOIN `twitter_content` ON `tracked_twitter`.`id` = `twitter_content`.`tracked_twitter_id` 
INNER JOIN `tracker_twitter_content` ON `twitter_content`.`id` = `tracker_twitter_content`.`twitter_content_id` 
WHERE `is_influencer` != '1' 
AND `tracker_twitter_content`.`tracker_id` = '88' 
AND `tracked_twitter_id` != '0' 
GROUP BY `tracked_twitter`.`id` 
ORDER BY twitterContentCount DESC 
LIMIT 20 
OFFSET 0 
+0

यदि आप 'LIMIT'-clause को हटाते हैं तो अनियंत्रित क्वेरी कितनी देर तक लेती है? एक अनियमित परिणाम-सेट में 'LIMIT' का मूल रूप से अर्थ है" मुझे कुछ मानदंड प्राप्त करें जो मेरे मानदंड से मेल खाते हैं "जबकि आदेशित परिणाम में इसका अर्थ है" मुझे मेरे पहले मानदंडों को प्राप्त करें जो मेरे मानदंड से मेल खाते हैं "और मूल रूप से इसका मतलब है कि आपको सभी को इंडेंट करना होगा उनमें से। –

+0

क्वेरी पर 'EXPLAIN' का आउटपुट क्या है? – raina77ow

+0

@ raina77ow मैंने प्रश्न में चित्र समझाया – Tamizharasan

उत्तर

3

distinct से छुटकारा पाने का प्रयास करें। वह एक प्रदर्शन हत्यारा है। मुझे यकीन नहीं है कि आपकी पहली क्वेरी जल्दी क्यों काम करती है; शायद MySQL इसे अनुकूलित करने के लिए पर्याप्त स्मार्ट है।

मैं कोशिश करेंगे: tracked_twitter(followers_count, id), twitter_content(tracked_twitter_id, id), और tracker_twitter_content(twitter_content_id, tracker_id):

SELECT tt.id 
FROM tracked_twitter tt 
WHERE EXISTS (SELECT 1 
       FROM twitter_content tc INNER JOIN 
        tracker_twitter_content ttc 
        ON tc.id = ttc.twitter_content_id 
       WHERE ttc.tracker_id = 88 AND 
        tt.id = tc.tracked_twitter_id 
      ) 
ORDER BY tt.followers_count DESC ; 

इस संस्करण के लिए, आप पर अनुक्रमित चाहते हैं।

+0

यह पूरी तरह से काम कर रहा है, और खंड द्वारा आदेश क्वेरी निष्पादन को धीमा नहीं करता है (20 कुल, क्वेरी ले ली गई 0.0707 सेकंड) भी। यदि आप क्वेरी की व्याख्या करते हैं तो मुझे खुशी होगी। ताकि मैं इस दृष्टिकोण पर ज्ञान प्राप्त करूंगा। और यदि आपके पास इन दृष्टिकोणों के बारे में पढ़ने के लिए कोई संदर्भ लिंक है, तो यह उपयोगी होगा। आपके उत्तर के लिए धन्यवाद। – Tamizharasan

+0

मुझे लगता है कि पहली क्वेरी जल्दी से काम करती है क्योंकि MySQL जानता है कि इसे केवल एक असाधारण सेट से 20 अलग-अलग रिकॉर्ड एकत्र करना होगा, जो शायद कम संख्या में पंक्तियों से आता है (आइए 20 से अधिक लेकिन हजारों से कम कहें)। लाखों प्रविष्टियों के आदेशित सेट से पहले 20 विशिष्ट प्राप्त करना बहुत धीमा होगा - अलग-अलग लाल हेरिंग का थोड़ा सा होगा और यह ऑर्डरबाय है जो समय ले रहा है, या शायद MySQL केवल ऑर्डर करने के लिए पर्याप्त गूंगा नहीं है, लेकिन फिर 20 –

+0

@CaiusJard लौटने से पहले लाखों पंक्तियों को भी अलग करें। । । असल में, मुझे लगता है कि MySQL डुप्लिकेट को रोकने के लिए 'आईडी' पर इंडेक्स का उपयोग कर सकता है - यह केवल क्रम में इंडेक्स पढ़ रहा है। स्पष्ट 'ऑर्डर बाय' के साथ, यह संभव नहीं है। –

1

जनक तालिका सीमा

SELECT DISTINCT `tracked_twitter`.id FROM 
(SELECT id,followers_count FROM tracked_twitter ORDER BY followers_count DESC 
LIMIT 20) AS tracked_twitter 
INNER JOIN `twitter_content` ON `tracked_twitter`.`id` = `twitter_content`.`tracked_twitter_id` 
INNER JOIN `tracker_twitter_content` ON `twitter_content`.`id` = `tracker_twitter_content`.`twitter_content_id` 
AND `tracker_twitter_content`.`tracker_id` = '88' 
ORDER BY tracked_twitter.followers_count DESC 
+0

यह उत्तर नहीं हो सकता है। क्योंकि आपने खंड द्वारा क्रमशः अन्य तालिकाओं की बाधा पर विचार नहीं किया था। इसलिए यह मूल तालिका से केवल 20 रिकॉर्ड लेता है और दूसरों के साथ जुड़ता है। जब मैं क्वेरी निष्पादित करता हूं तो मुझे केवल दो पंक्तियां मिलती हैं। – Tamizharasan

1

मुख्य समस्या यह है कि आप अपेक्षाकृत कुछ पंक्तियों में दिखाई भी, आप एक प्राथमिक कुंजी (पूर्णांक के बजाय) के रूप में है और इसलिए में विदेशी कुंजी के रूप में varchar(255) COLLATE utf8_unicode_ci का उपयोग है साथ ब्रैकेट पर रखने अन्य टेबल मुझे एक ही समस्या है, मुझे संदेह है, twitter_content.id के साथ है। इससे बहुत लंबी स्ट्रिंग तुलना होती है और अस्थायी तालिकाओं के लिए बहुत अधिक मेमोरी आरक्षित होती है।

स्वयं क्वेरी के बारे में, हाँ, यह एक प्रश्न होना चाहिए जो followers_count अनुक्रमणिका के साथ चलता है और संबंधित तालिकाओं के लिए स्थिति की जांच करता है। यह गॉर्डन लिनॉफ़ ने सुझाव दिया था, या इंडेक्स संकेतों का उपयोग करके किया जा सकता है।