2009-08-07 10 views
5

मेरे पास एक बड़ी तालिका (टोकन फ़्रिक्वेंसी) है जिसमें लाखों पंक्तियां हैं। TokenFrequency मेज है कि इस तरह संरचित है:एसक्यूएल वैकल्पिक एक एकल टेबल पर एक INNER जॉइन करने के लिए वैकल्पिक

तालिका - TokenFrequency

  • आईडी - int, प्राथमिक कुंजी
  • स्रोत - पूर्णांक, विदेशी कुंजी
  • टोकन - चार
  • गिनती - int

मेरा लक्ष्य उन सभी पंक्तियों का चयन करना है जिनमें दो स्रोतों में एक ही टोकन है। उदाहरण के लिए मेरी मेज इस तरह दिख रही है, तो:

आईडी --- स्रोत --- टोकन --- गिनती
1 ------ 1 --------- कुत्ते - ----- 1
2 ------ 2 --------- बिल्ली -------- 2
3 ------ 3 ----- ---- बिल्ली -------- 2
4 ------ 4 --------- सुअर -------- 5
5 ---- - 5 --------- चिड़ियाघर ------- 1
6 ------ 5 --------- बिल्ली -------- 1
7 ------ 5 --------- सुअर -------- 1

मैं एक एसक्यूएल क्वेरी चाहता हूं कि मुझे स्रोत 1, स्रोत 2, और गणना की राशि दें। उदाहरण के लिए:

source1 --- source2 --- टोकन --- गिनती
---- 2 ----------- 3 --------- बिल्ली -------- 4
---- 2 ----------- 5 --------- बिल्ली -------- 3
---- 3 ----------- 5 --------- बिल्ली -------- 3
---- 4 ------- ---- 5 --------- सुअर -------- 6

मैं एक प्रश्न है कि इस तरह दिखता है:

SELECT F.source AS source1, S.source AS source2, F.token, 
     (F.count + S.count) AS sum 
FROM  TokenFrequency F 
INNER JOIN TokenFrequency S ON F.token = S.token 
WHERE F.source <> S.source 

इस क्वेरी ठीक काम करता है लेकिन मैं इसे साथ है कि समस्याओं कि कर रहे हैं:

  1. मैं एक TokenFrequency तालिका पंक्तियों के लाखों लोगों की है कि है और इसलिए इस परिणाम प्राप्त करने के लिए एक तेजी से विकल्प की जरूरत है।
  2. मेरे पास वर्तमान क्वेरी जो डुप्लिकेट दे रही है। इसके उदाहरण के लिए चयन:
    source1 = 2, source2 = 3, टोकन = बिल्ली, गिनती 4 =
    source1 = 3, source2 = 2, टोकन = बिल्ली, गिनती 4 =
    कौन सा एक समस्या की बहुत अधिक नहीं है लेकिन अगर उनको दूर करने का एक तरीका है और बदले में गति बढ़ाना है तो यह बहुत उपयोगी होगा

मेरे पास जो मुख्य मुद्दा है, वह मेरी वर्तमान क्वेरी के साथ क्वेरी की गति है, इसे पूरा होने में घंटों लगते हैं। एक टेबल पर INNER जॉइन जो मैं मानता हूं वह समस्या है। मुझे यकीन है कि आंतरिक जुड़ने को खत्म करने और टोकन फ़्रिक्वेंसी तालिका के एक उदाहरण का उपयोग करके समान परिणाम प्राप्त करने का एक तरीका होना चाहिए। मैंने जो दूसरी समस्या का उल्लेख किया है वह भी क्वेरी में गति वृद्धि को बढ़ावा दे सकता है।

मुझे इस क्वेरी को पुन: स्थापित करने का एक तरीका चाहिए ताकि एक ही परिणाम तेज, अधिक कुशल तरीके से प्रदान किया जा सके।

धन्यवाद।

+1

क्या आप क्वेरी के EXPLAIN पोस्ट कर सकते हैं (http://dev.mysql.com/doc/refman/5.0/en/explain.html)। इससे लोगों को यह देखने में मदद मिलेगी कि वे आपको अनुकूलित करने में कैसे मदद कर सकते हैं। –

+0

आपको कुछ इंडेक्स जानकारी, कौन से कॉलम इत्यादि देने की आवश्यकता है –

+0

यहां प्रारंभिक रूप से पोस्ट की गई मेरी क्वेरी का विस्तार है। आईडी: 1, select_type: सरल, तालिका: एफ एंड एस, प्रकार: सभी, संभावित_की: पूर्ण, कुंजी: पूर्ण, कुंजी_लेन: पूर्ण, रेफरी: नल, पंक्तियां: 8, अतिरिक्त: कहां उपयोग करना; बफर का उपयोग करके दो पंक्तियां लौटाई गई हैं, केवल दो पंक्तियों का नाम है एफ और एस – cruzja

उत्तर

2

मैं, कुछ और जानकारी की आवश्यकता होगी गति समस्या का निदान करने के लिए, लेकिन dups दूर करने के लिए कहां से जोड़ें:

SELECT token, GROUP_CONCAT(source), SUM(count) 
FROM TokenFrequency 
GROUP BY token; 

यह चलाना चाहिए:

AND F.source<S.source 
+0

आह इतना आसान है। यह डुप्लिकेट को खत्म करने के लिए पूरी तरह से काम किया। सही दृष्टिकोण के लिए धन्यवाद – cruzja

2

इस प्रयास करें बहुत तेज़ और डुप्लिकेट को भी खत्म कर दें। लेकिन स्रोतों को अल्पविराम से अलग सूची में वापस कर दिया जाएगा, इसलिए आपको अपने आवेदन में विस्फोट करना होगा।

तुम भी कॉलम token, source, count (इसी क्रम में) पर एक यौगिक सूचकांक बनाने का प्रयास करें और EXPLAIN साथ विश्लेषण करता है, तो MySQL बहुत चालाक इस प्रश्न के लिए एक covering index के रूप में उपयोग करने के लिए है देखने के लिए हो सकता है।


अद्यतन: मैं आपके सवाल का गलत समझा है लगते हैं। आप प्रति टोकन की गणना नहीं करना चाहते हैं, आप किसी दिए गए टोकन के लिए स्रोतों की प्रत्येक जोड़ी के लिए गणना की राशि चाहते हैं।

मेरा मानना ​​है कि आंतरिक शामिल इस के लिए सबसे अच्छा समाधान है। एसक्यूएल के लिए एक महत्वपूर्ण दिशानिर्देश यह है कि यदि आपको दो अलग-अलग पंक्तियों के संबंध में अभिव्यक्ति की गणना करने की आवश्यकता है, तो आपको शामिल होने की आवश्यकता है।

हालांकि, ऊपर वर्णित एक अनुकूलन तकनीक का उपयोग सूचकांक को कवर करने के लिए है ताकि आपको आवश्यक सभी कॉलम इंडेक्स डेटा स्ट्रक्चर में शामिल किए जाएं। लाभ यह है कि आपके सभी लुकअप ओ (लॉग एन) हैं, और क्वेरी को अन्य कॉलम प्राप्त करने के लिए भौतिक पंक्ति पढ़ने के लिए दूसरा I/O करने की आवश्यकता नहीं है।

इस मामले में, आपको उपरोक्त वर्णित कॉलम token, source, count पर कवर इंडेक्स बनाना चाहिए। पर्याप्त कैश स्पेस आवंटित करने का प्रयास करें ताकि सूचकांक को स्मृति में कैश किया जा सके।

+1

+1; लेकिन इस तरह की एक सूचकांक पूरे रिकॉर्ड के रूप में लगभग बड़ी होगी, क्या आपको लगता है कि यह सिर्फ टोकन पर अनुक्रमणित करने से तेज होगा? – Javier

+0

पंक्तियों और अन्य सिस्टम-विशिष्ट कारकों की संख्या पर निर्भर करता है। सुनिश्चित करने का एकमात्र तरीका यह है कि इसे * अपने * डेटाबेस के साथ आज़माएं और प्रदर्शन को मापें। –

+0

यह एक अच्छा दृष्टिकोण है, लेकिन एकमात्र समस्या यह है कि यदि आपके पास एक टोकन है जो एक से अधिक स्रोतों में है तो आपको उन सभी मामलों को एक साथ जोड़ा जाता है।उदाहरण के लिए मेरे उदाहरण के मामले में टोकन "बिल्ली" स्रोत 2,3, और 5 में है इसलिए इसलिए मुझे 2, 3 और 5 की गिनती के साथ 2 और 3 की गिनती के साथ मुझे 2 और 3 देने के बजाय 5 की गिनती मिलती है, और 3 और 5 के साथ 3. मेरी वास्तविकता में, डेटा के बड़े सेट में टोकन हैं जो लगभग हर दस्तावेज़ में दिखाई देते हैं जो मुझे हजारों स्रोतों और उनके सम्मान की संख्या के GROUP_CONCAT प्रदान करेगा। – cruzja

1

यदि टोकन अनुक्रमित नहीं है, तो यह निश्चित रूप से होना चाहिए।