2008-08-28 12 views
21

के साथ काम अगर मैं की तरह एक प्रश्न है:अनुक्रमणिका "में" खंड

Select EmployeeId 
From Employee 
Where EmployeeTypeId IN (1,2,3) 

और मैं EmployeeTypeId मैदान पर एक सूचकांक है, एसक्यूएल सर्वर अभी भी है कि इंडेक्स का उपयोग करता है?

+2

मुझे समझ में नहीं आता कि यह वास्तविक सवाल क्यों नहीं है। – nawfal

+0

मुझे या तो? यह सही सवाल है कि मैं क्रमबद्ध करने की कोशिश करने के लिए यहां आया था और इसने मुझे काम करने के लिए जानकारी का एक बड़ा टुकड़ा दिया। –

+0

@nawfal के लिए +1 - मैं भी वही महसूस करता हूं। –

उत्तर

13

हाँ, यह सही है। यदि आपकी कर्मचारी तालिका में 10,000 रिकॉर्ड हैं, और केवल 5 अभिलेखों में नियोक्ता टाइप (1,2,3) है, तो यह रिकॉर्ड को लाने के लिए सूचकांक का अधिकतर उपयोग करेगा। हालांकि, अगर यह पता चलता है कि 9,000 रिकॉर्ड्स में कर्मचारी आईडी टाइप (1,2,3) है, तो यह संभवतः संबंधित कर्मचारी आईडी प्राप्त करने के लिए टेबल स्कैन करेगा, क्योंकि यह पूरी तालिका के माध्यम से बस जाने के लिए तेज़ है इंडेक्स पेड़ की प्रत्येक शाखा और रिकॉर्ड अलग-अलग देखें।

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

Select EmployeeId From Employee WITH (Index(Index_EmployeeTypeId)) Where EmployeeTypeId IN (1,2,3) 

सूचकांक EmployeeTypeId मैदान पर आप यह मानते हुए Index_EmployeeTypeId नाम पर है।

4

आमतौर पर यह तब तक होगा जब तक कि इन क्लॉज में तालिका का अधिकतर भाग शामिल न हो, और फिर यह तालिका स्कैन करेगा। आपके विशिष्ट मामले में पता लगाने का सबसे अच्छा तरीका क्वेरी विश्लेषक में इसे चलाने के लिए होगा, और निष्पादन योजना देखें।

2

तो वहाँ एक "में" खंड एक मेज स्कैन चलाने के लिए संभावित है, लेकिन अनुकूलक कोशिश करते हैं और इससे निपटने के लिए सबसे अच्छा तरीका है बाहर काम करेंगे?

चाहे किसी इंडेक्स का उपयोग किया जाता है, क्वेरी के प्रकार पर इतनी भिन्नता नहीं है कि तालिका में डेटा के प्रकार और वितरण के प्रकार, आपके टेबल आंकड़े कितने अद्यतित हैं, और कॉलम का वास्तविक डेटाटाइप।

अन्य पोस्टर सही हैं कि एक सूचकांक एक मेज पर इस्तेमाल किया जाएगा यदि स्कैन:

  • क्वेरी अधिक अनुक्रमित पंक्तियों की एक निश्चित प्रतिशत की तुलना में 10% का उपयोग करेंगे नहीं (जैसे कि ~ लेकिन भिन्न हो जाना चाहिए डीबीएमएस के बीच)।
  • वैकल्पिक रूप से, यदि बहुत सारी पंक्तियां हैं, लेकिन कॉलम में अपेक्षाकृत कुछ अद्वितीय मान हैं, तो यह तालिका स्कैन करने के लिए भी तेज़ हो सकता है।

अन्य वैरिएबल जो स्पष्ट नहीं हो सकता है यह सुनिश्चित कर रहा है कि मूल्यों की डेटाटाइप की तुलना समान है। PostgreSQL में, मुझे नहीं लगता कि अगर आप फ्लोट पर फ़िल्टर कर रहे हैं तो इंडेक्स का उपयोग किया जाएगा लेकिन आपका कॉलम इनट्स से बना है। ऐसे कुछ ऑपरेटर भी हैं जो इंडेक्स उपयोग का समर्थन नहीं करते हैं (फिर, PostgreSQL में, ILIKE ऑपरेटर इस तरह है)।

जैसा कि उल्लेख किया गया है, हमेशा संदेह में और आपके डीबीएमएस के दस्तावेज़ आपके मित्र होने पर क्वेरी विश्लेषक की जांच करें।

3

जब तक कि तकनीक देर से कल्पना नहीं कर पाती है, तब तक "आईएन" क्वेरी दिखाए जाने वाले परिणाम का परिणाम नतीजा होगा जो तीन परिणाम सेटों का प्रभावी ढंग से OR-ing है, "IN" में प्रत्येक मान के लिए एक सूची। आईएन क्लॉज प्रत्येक सूची के लिए समानता शर्त बन जाता है और यदि उपयुक्त हो तो सूचकांक का उपयोग करेगा। अद्वितीय आईडी और बड़ी पर्याप्त तालिका के मामले में, मैं आशा करता हूं कि ऑप्टिमाइज़र इंडेक्स का उपयोग करे।

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

यह संभवतः मूक है - एक कर्मचारी तालिका की तरह कुछ ऐसा छोटा होने की संभावना है कि यह स्मृति में कैश रहेगा और आप शायद उस और अनुक्रमित पुनर्प्राप्ति के बीच कोई अंतर नहीं देखेंगे।

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

1

@ माइक: विस्तृत विश्लेषण के लिए धन्यवाद। निश्चित रूप से वहां कुछ दिलचस्प बिंदु हैं जो आप करते हैं। मैंने जो उदाहरण पोस्ट किया वह कुछ मामूली है लेकिन सवाल का आधार NHibernate का उपयोग करने से आया था।

NHibernate के साथ

, तो आप इस तरह के एक खंड लिख सकते हैं:

int[] employeeIds = new int[]{1, 5, 23463, 32523}; 
NHibernateSession.CreateCriteria(typeof(Employee)) 
.Add(Restrictions.InG("EmployeeId",employeeIds)) 

NHibernate तो एक प्रश्न जो दिखता है

select * from employee where employeeid in (1, 5, 23463, 32523) 

की तरह तो जैसा कि आप और अन्य लोगों ने बताया है, यह वहाँ की तरह दिखता है उत्पन्न करता है ऐसे समय होने जा रहे हैं जहां एक इंडेक्स का उपयोग किया जाएगा या एक टेबल स्कैन होगा, लेकिन आप वास्तव में रनटाइम तक निर्धारित नहीं कर सकते हैं।

0
Select EmployeeId From Employee USE(INDEX(EmployeeTypeId)) 

यह क्वेरी आपके द्वारा बनाई गई इंडेक्स का उपयोग करके खोज करेगी। इससे मेरा काम बनता है। कृपया प्रयास करें ..

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