2009-05-27 15 views
10

मैं एसक्यूएल में अच्छा नहीं हूं।सरल कैसे गति करें

मैं इस तरह शामिल होने के लिए एक सरल में तेजी लाने के लिए एक रास्ता खोज रहा:

SELECT 
    E.expressionID, 
    A.attributeName, 
    A.attributeValue 
FROM 
    attributes A 
JOIN 
    expressions E 
ON 
    E.attributeId = A.attributeId 

मैं हजारों बार की इस दर्जनों कर रहा हूँ और यह अधिक से अधिक के रूप में मेज बड़ा हो जाता है ले रहा है।

मैं अनुक्रमित में सोच रहा हूँ - लेकिन मैं डॉन '- मैं एक टेबल पर चयन में तेजी लाने के मैं शायद गुण तालिका के लिए भाव तालिका के लिए expressionID पर nonclustered अनुक्रमणिका डाल चाहते हैं और एक अन्य पर (AttributeName, attributeValue) था टी यह नहीं जानता कि यह शामिल होने पर कैसे लागू हो सकता है।

संपादित: मैं पहले से ही गुण तालिका

मैंने पर एक संकुल attributeId (पी) पर भाव मेज पर expressionId (पी), attributeId (पी, FK) पर सूचकांक और एक अन्य क्लस्टर सूचकांक this प्रश्न देखा लेकिन मैं कुछ और सामान्य और शायद कहीं अधिक सरल पूछ रहा हूं।

किसी भी मदद की सराहना की!

+0

क्या आपके पास इस प्रश्न में WHERE क्लॉज है? कितनी पंक्तियां वापस आ रही हैं? – JerSchneid

+0

नहीं कहां - मैं इसका उपयोग एक अस्थायी तालिका को पॉप्युलेट करने के लिए कर रहा हूं, जिसे मिलान-अभिव्यक्ति प्राप्त करने के लिए नाम-मूल्य जोड़े के सेट के आधार पर कई जगहों के साथ फ़िल्टर किया गया है ID – JohnIdol

+1

आपको अपनी क्वेरी के उस दूसरे भाग को पोस्ट करना चाहिए। मैं शर्त लगाता हूं कि धीमी गति उस अस्थायी तालिका में बड़ी संख्या में रिकॉर्ड डालने के कारण होती है। यह शायद उन्हें संयोजित करके काफी सुधार किया जा सकता है ताकि विशाल सम्मिलन को रोकने के लिए पहले WHERE क्लॉज का उपयोग किया जा सके। – JerSchneid

उत्तर

16

आप निश्चित रूप से पर attributes और expressions तालिका पर इंडेक्स होना चाहते हैं। यदि आपके पास वर्तमान में उन इंडेक्स मौजूद नहीं हैं, तो मुझे लगता है कि आपको एक बड़ी गति दिखाई देगी।

+5

भूलना नहीं भूलना कि दोनों कॉलम एक ही डेटा प्रकार का होना चाहिए, और, यदि वे एक ही संयोजन के चरित्र डेटा हैं। – Tomalak

+1

प्राथमिक कुंजी को जानना मदद करेगा। एक कुंजी जो प्राथमिक कुंजी है पहले से ही अनुक्रमित किया जाएगा। यह संभव है कि आपकी अभिव्यक्ति तालिका में दो फ़ील्ड हों जो प्राथमिक कुंजी बनाते हैं। इसका मतलब है कि E.attributeId पर एक इंडेक्स बनाना जाने का तरीका होगा। प्राथमिक कुंजी E.ID और E.attributeId दोनों का उपयोग करके एक अनुक्रमणिका बनायेगी। केवल E.attributeId के लिए एक इंडेक्स जोड़ना इसे तेज करेगा। – Kieveli

+1

दरअसल, प्राथमिक कुंजी सभी प्लेटफार्मों पर ऑटोइंडेक्स नहीं किया जाता है। उदाहरण के लिए MySQL प्राथमिक कुंजी पर डिफ़ॉल्ट रूप से एक अनुक्रमणिका बना नहीं है। –

6

वास्तव में, क्योंकि वहाँ बहुत कुछ कॉलम लौटाए जाने हैं, मैं इस क्वेरी

अर्थात एक सूचकांक कि क्वेरी में सभी क्षेत्रों में शामिल हैं के लिए एक कवर सूचकांक पर विचार करेंगे।

+0

पर संपादित करें मैं कैसे शामिल होने के सूचकांक? (कभी नहीं किया गया) – JohnIdol

+2

मुझे लगता है कि गोबलीन ए। एट्रिब्यूटआईड, एट्रिब्यूटनाम, एट्रिब्यूटवैल्यू और ई.एट्रिब्यूटआईडी और ई.एक्सप्रेसियन आईडी पर एक इंडेक्स जोड़ने का सुझाव दे रहा है ... लेकिन मैं 100% निश्चित नहीं हूं। इसका सिद्धांत यह है कि क्वेरी के लिए सभी डेटा सीधे सूचकांक से आएंगे और कभी भी टेबल पर नहीं आते। – Greg

+0

क्षमा करें, मैं उस पर स्पष्ट नहीं था। ग्रेग सही है। इस उदाहरण में दो कवर किए गए इंडेक्स होंगे, प्रत्येक तालिका के लिए एक और वास्तविक तालिका को शामिल किए बिना दो कवर किए गए इंडेक्स के बीच शामिल होगा। –

3

कुछ चीज़ों के बारे में की जरूरत है अनुक्रमित, क्वेरी योजना और आंकड़े हैं।

विशेषता पर इंडेक्स रखें Id। या, सुनिश्चित करें कि इंडेक्स मौजूद हैं जहां विशेषता आईडी कुंजी में पहला कॉलम है (SQL सर्वर अभी भी इंडेक्स का उपयोग कर सकता है यदि यह पहला कॉलम नहीं है, लेकिन यह तेज़ नहीं है)।

हाइलाइट क्वेरी विश्लेषक में क्वेरी और मारा^एल योजना को देखने के लिए। आप देख सकते हैं कि टेबल एक साथ कैसे जुड़ते हैं। लगभग हमेशा की तरह, अनुक्रमित का उपयोग नहीं से बेहतर है (वहाँ हाशिये मामलों में जहां अगर एक मेज काफी छोटा है, अनुक्रमित आप धीमा कर सकते हैं कर रहे हैं - लेकिन अभी के लिए, बस ध्यान रखें कि समय अनुक्रमित के 99% अच्छा कर रहे हैं)।

ऑर्डर पर ध्यान दें जिसमें टेबल शामिल हैं। SQL सर्वर तालिका आकारों पर आंकड़े बनाए रखता है और यह निर्धारित करेगा कि पहले कौन सा शामिल होना बेहतर है। आंकड़ों को अद्यतन करने के लिए आंतरिक SQL सर्वर प्रक्रियाओं पर कुछ जांच करें - यह बहुत लंबा रहा है इसलिए मेरे पास यह जानकारी आसान नहीं है।

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

1

एक और बात करने के लिए इस तरह की कुछ अनुक्रमित जोड़ने है:

attributes.{attributeId, attributeName, attributeValue} 
expressions.{attributeId, expressionID} 

यह hacky है! लेकिन उपयोगी है अगर यह एक अंतिम उपाय है।

यह क्या करता है एक प्रश्न योजना है कि अनुक्रमित द्वारा "पूरी तरह से जवाब" किया जा सकता है बनाने के लिए है। आम तौर पर, एक सूचकांक वास्तव में आपकी उपरोक्त क्वेरी में डबल-आई/ओ का कारण बनता है: एक सूचकांक को हिट करने के लिए (यानी।तालिका में जांच), सूचकांक द्वारा संदर्भित वास्तविक पंक्ति लाने के लिए दूसरा (विशेषता नाम खींचने के लिए, आदि)।

यह विशेष रूप से सहायक होता है यदि "गुण" या "अभिव्यक्ति" एक विस्तृत तालिका है। यही वह तालिका है जो पंक्तियों को लाने के लिए महंगा है।

अंत में, आपकी क्वेरी को गति देने का सबसे अच्छा तरीका है WHERE क्लॉज जोड़ना!

+0

पर रिपोर्ट करूंगा, क्या वे इंडेक्स मुझे सम्मिलन पर मार देंगे? के बारे में कहां - मैं इस टेम्पलेट टेबल को पॉप्युलेट करने के लिए शामिल हूं जिसका उपयोग मैं नाम-मूल्य जोड़े (विशेषताओं) के दिए गए सेट के लिए अभिव्यक्ति आईडी (यदि कोई है) खोजने के लिए कर रहा हूं। तो मुझे लगता है कि मैं इस क्वेरी पर – JohnIdol

+0

को गति देने के लिए विशेषता/नामों को वितरित कर सकता हूं, मुझे गतिशील रूप से या संयोजनों को जोड़ना होगा, क्योंकि मुझे जहां कहीं भी smt की आवश्यकता है (attributeName = 'X' और विशेषताValue = 'Y') या (विशेषता नाम = 'ज़ेड' और विशेषता Value = 'डब्ल्यू') ... और बहुत आगे! तो मैं शायद नाम मूल्य जोड़ों के साथ तालिका के माध्यम से लूपिंग खो देता हूं और इन खंडों का निर्माण – JohnIdol

+0

प्रविष्टियों के लिए हमेशा इंडेक्स का ट्रेडऑफ होता है। दोबारा (और दुर्भाग्य से), कोई भी आकार-फिट नहीं है-सभी जवाब। यदि आपके पास केवल एक या दो इंडेक्स हैं, और इसे देखते हुए क्लस्टर नहीं किया गया है, तो संभवतः यह आपको मारने वाला नहीं है। उस ने कहा, यह एक सूचकांक है जो एक विशिष्ट क्वेरी की ओर बहुत अधिक तैयार है, इसलिए अपने विवेकानुसार उपयोग करें। – Matt

2

मुझे लगता है कि आपकी समस्या उस temp तालिका में डाली जा रही पंक्तियों की एक बड़ी संख्या है। क्या आप SELECT डेटाबेस में हर पंक्ति से पहले WHERE खंड जोड़ सकते हैं?

+0

मुझे लगता है कि मैं इसे सत्यापित करने के लिए इस क्वेरी पर विशेषता नाम + विशेषतावृत्त के साथ फ़िल्टर कर सकता हूं या विघटित कर सकता हूं लेकिन समस्या यह है कि मैं मुझे गतिशील रूप से या संयोजन को जोड़ना होगा क्योंकि मुझे जहां की आवश्यकता है (attributeName = 'X' और विशेषता Value = 'Y') या विशेषता (नाम '=' Z 'और विशेषता Value =' W ') ... अंत में प्राप्त करने के लिए नाम-मूल्य जोड़े के दिए गए सेट का अभिव्यक्ति आईडी। इसलिए मैं शायद नाम-मूल्य जोड़ों के साथ तालिका के माध्यम से लूपिंग खो देता हूं और इन्हें बना रहा हूं या WHERE क्लॉज के लिए संयोजन करता हूं। – JohnIdol

+1

अभी भी बेहतर हो सकता है? या आप उस अस्थायी तालिका को कैशिंग में देख सकते हैं। या तो इसे कुछ मध्यम-स्तरीय मेमोरी में कैशिंग कर रहा है, या उस अस्थायी तालिका को एक स्थायी तालिका बना रहा है और इसे केवल तब अपडेट कर रहा है जब अन्य तालिकाओं की पंक्तियां बदलती हैं? – JerSchneid

+0

अगर मुझे इंडेक्स के साथ महत्वपूर्ण सुधार नहीं मिल पा रहे हैं तो मैं पिछली टिप्पणी के वर्णन के रूप में शामिल होने के गतिशील फ़िल्टरिंग के साथ जाऊंगा - मैं पेसिस्टेंट कैशिंग टेबल रखने से बचना चाहता हूं! – JohnIdol

1

मैं अपने स्कीमा सही ढंग से समझ रहा हूँ, तो आप यह कहते हुए हैं यदि वह आपके टेबल थोड़े इस तरह दिखेगा:

Expressions: PK - ExpressionID, AttributeID 
Attributes: PK - AttributeID 

यह मानते हुए कि प्रत्येक पी संकुल अनुक्रमणिका, अभी भी एक है कि इसका मतलब है कि है अभिव्यक्ति तालिका पर इंडेक्स स्कैन की आवश्यकता है। आप अभिव्यक्ति तालिका पर एक इंडेक्स बनाने पर विचार करना चाहेंगे जैसे: विशेषता आईडी, अभिव्यक्ति आईडी। यह इंडेक्स स्कैनिंग को रोकने में मदद करेगा जो वर्तमान में होता है।

+0

आपकी समझ सही है। आप क्लस्टरेड इंडेक्स के अलावा अभिव्यक्तियों पर अभिव्यक्ति पर एक नॉनक्लस्टर्ड इंडेक्स जोड़ना चाहते हैं जो पहले से मौजूद है? – JohnIdol

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