2009-04-06 6 views
15

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

धन्यवाद

उत्तर

20

अनुकूलक सोचता है कि पूर्ण तालिका स्कैन बेहतर होगा।

यदि कुछ NULL पंक्तियां हैं, तो अनुकूलक सही है।

आप पूरी तरह यकीन है कि सूचकांक का उपयोग किया जाएगा रहे हैं तेजी से, तो आपकी क्वेरी संकेत (, आप col1 IS NULL साथ एक से अधिक 75% पंक्तियों है):

SELECT /*+ INDEX (t index_name_on_col1) */ 
     * 
FROM mytable t 
WHERE col1 IS NOT NULL 

क्यों 75%?

क्योंकि का उपयोग कर सूचकांक द्वारा कवर नहीं मान प्राप्त करने के लिए छिपा हुआ ROWID पर शामिल होने के, जो 4 के बारे में कई बार के रूप में ज्यादा लागत तालिका स्कैन के रूप में निकलता है।

यदि सूचकांक श्रेणी में 25% पंक्तियों से अधिक शामिल है, तो टेबल स्कैन आमतौर पर तेज़ होता है।

जैसा कि Tony Andrews द्वारा वर्णित है, क्लस्टरिंग कारक इस मान को मापने के लिए अधिक सटीक विधि है, लेकिन 25% अभी भी अंगूठे का एक अच्छा नियम है।

+1

क्वास्नोई, आपको वह 75% कहां मिल रहा है? यदि कोई लाख पंक्तियां हैं और केवल एक शून्य है, तो उस कॉलम पर एक इंडेक्स का उपयोग टेबल स्कैन से धीमा क्यों होगा? – tpdi

+1

क्योंकि सूचकांक ROWID पर एक छिपी हुई भागीदारी को लागू करता है, जिसकी तालिका स्कैन के रूप में लगभग 4 गुना अधिक खर्च होता है। क्या सूचकांक चयन 25% से कम है, तालिका स्कैन आमतौर पर तेज़ होता है। – Quassnoi

+2

एक पूर्ण तालिका स्कैन में, आप बस तालिका में सभी पंक्तियों पर फिर से शुरू होते हैं; यदि आप इंडेक्स स्कैन करते हैं, तो आपको पहले इंडेक्स को पढ़ना होगा, और उसके बाद टेबल को पढ़ना होगा। एक निश्चित बिंदु से एक सूचकांक पढ़ने की लागत पूरी तालिका को पढ़ने से कहीं अधिक है। – andri

2

आप एक का चयन करें * क्या कर रहे हैं, तो यह समझ बनाने के सूचकांक का उपयोग कर के बजाय एक मेज स्कैन करने के लिए होगा। यदि आप जानते हैं कि आप कौन से कॉलम में रूचि रखते हैं, तो आप उन कॉलम के साथ एक कवर इंडेक्स बना सकते हैं, जिसे आप लागू कर रहे हैं, वह पूरी स्थिति नहीं है।

0

उस कॉलम पर एक अनुक्रमणिका बनाएं।

यह सुनिश्चित करने के लिए कि इंडेक्स का उपयोग किया जाता है, यह सूचकांक और अन्य कॉलम पर होना चाहिए।

जवाब ocdecio:

आप एक का चयन करें * क्या कर रहे हैं, तो यह समझ बनाने होगा सूचकांक उपयोग करने के बजाय एक मेज स्कैन करने के लिए।

यह सख्ती से सच नहीं है; एक इंडेक्स का उपयोग किया जाएगा यदि कोई ऐसा इंडेक्स है जो आपके क्लॉज को फिट करता है, और क्वेरी ऑप्टिमाइज़र उस इंडेक्स का उपयोग करने का निर्णय लेता है तो टेबल स्कैन करने से तेज़ होगा। यदि कोई इंडेक्स नहीं है, या कोई उपयुक्त इंडेक्स नहीं है, तो केवल एक टेबल स्कैन किया जाना चाहिए।

+0

चयन * पर महान टिप्पणियां हालांकि स्पष्ट करने के लिए - हम अन्य कारणों से उपयोगकर्ता कभी भी चयन नहीं करते हैं - हम हमेशा चयन कॉलम में हमारी कॉलम सूची शामिल करते हैं। –

15

ऑप्टिमाइज़र पूर्ण तालिका स्कैन की सापेक्ष लागत और इंडेक्स का उपयोग करके अपना निर्णय लेगा। यह मुख्य रूप से नीचे आता है कि क्वेरी को संतुष्ट करने के लिए कितने ब्लॉक पढ़ना होगा। किसी अन्य उत्तर में उल्लिखित अंगूठे का 25%/75% नियम सरल है: कुछ मामलों में एक पूर्ण तालिका स्कैन भी पंक्तियों का 1% प्राप्त करने के लिए समझ में आ जाएगा - यानी यदि उन पंक्तियों को कई ब्लॉक के आसपास फैलाना होता है। आप देख सकते हैं, टी 1 में पंक्तियों की केवल लगभग 1% एक गैर-शून्य object_id है

SQL> create table t1 as select object_id, object_name from all_objects; 

Table created. 
SQL> alter table t1 modify object_id null; 

Table altered. 

SQL> update t1 set object_id = null 
    2 where mod(object_id,100) != 0 
    3/

84558 rows updated. 

SQL> analyze table t1 compute statistics; 

Table analyzed. 

SQL> select count(*) from t1 where object_id is not null; 

    COUNT(*) 
---------- 
     861  

:

उदाहरण के लिए, इस तालिका पर विचार करें।लेकिन जिस तरह से मैंने टेबल बनाया है, इन 861 पंक्तियों को मेज के चारों ओर समान रूप से समान रूप से फैलाया जाएगा। इसलिए, क्वेरी:

select * from t1 where object_id is not null; 

अनुकूलक सूचकांक का इस्तेमाल किया है, भले ही, टी 1 में लगभग हर ब्लॉक का दौरा करने के डेटा प्राप्त करने की संभावना है। यह सूचकांक के साथ बांटने और पूर्ण टेबल स्कैन के लिए जाने के लिए समझ में आता है!

एक प्रमुख आंकड़ा मदद करने के लिए इस स्थिति की पहचान सूचकांक क्लस्टरिंग कारक है:

SQL> select clustering_factor from user_indexes where index_name='T1_IDX'; 

CLUSTERING_FACTOR 
----------------- 
       460 

यह मान 460 बहुत अधिक है (सूचकांक में 861 पंक्तियों की तुलना में), और पता चलता है कि एक पूर्ण तालिका स्कैन करेगा इस्तेमाल किया गया। this DBAZine article on clustering factors देखें।

1

यह आपके टेबल पर मौजूद इंडेक्स के प्रकार पर निर्भर कर सकता है।

अधिकांश बी-पेड़ इंडेक्स स्टोर नल प्रविष्टियां नहीं करते हैं। बिटमैप इंडेक्स स्टोर नल प्रविष्टियां करें।

तो, अगर आपके पास:

चयन * से mytable जहाँ MyColumn अशक्त

है और आप mycolumn पर एक मानक बी पेड़ सूचकांक, तो प्रश्न हैं नहीं कर सकते इंडेक्स का उपयोग करें क्योंकि "शून्य" इंडेक्स में नहीं है।

(सूचकांक एकाधिक स्तंभों के खिलाफ है, और अनुक्रमित स्तंभों में से एक फिर वहाँ सूचकांक में एक प्रविष्टि होगी। अशक्त नहीं है, तो)

+1

संबंधित प्रश्न 'शून्य नहीं है' लुकअप है, न कि शून्य है। – KajMagnus

+0

फिर भी, यह उपयोगी जानकारी –

0

यह भी देखना हो मेज पर ओरेकल के आंकड़े कर रहे हैं लायक है तारीख। यह नहीं पता कि एक पूर्ण टेबल स्कैन धीमा हो जाएगा।

-1

देखें http://www.oracloid.com/2006/05/using-index-for-is-null/

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

create index tind on t(field_to_index, 1); 
0

Oracle डाटाबेस नियमित (ख-वृक्ष) सूचकांकों में बिल्कुल नहीं सूचकांक शून्य मान करते हैं, तो यह उपयोग नहीं कर सकते और न ही आप कर सकते हैं ' इसका उपयोग करने के लिए ऑरैक डेटाबेस को मजबूर करें।

बीआर

+0

है यह प्रश्न 'शून्य नहीं है' के बारे में है। सभी प्रासंगिक मान सूचकांक में होंगे। –

0

का उपयोग करते हुए संकेत केवल एक काम के आसपास के बजाय एक समाधान के रूप में किया जाना चाहिए।

जैसा कि अन्य उत्तरों में बताया गया है, शून्य मूल्य बी-ट्री इंडेक्स में उपलब्ध नहीं है।

चूंकि आप जानते हैं कि इस कॉलम में आपके पास अधिकतर शून्य मान हैं, तो आप उदाहरण के लिए शून्य मान को शून्य से प्रतिस्थापित कर पाएंगे।

यह वास्तव में, आम तौर पर अपने कॉलम और अपने डेटा की प्रकृति पर निर्भर करता है लेकिन अगर आपके स्तंभ उदाहरण के लिए दिनांक प्रकार है:

where mydatecolumn is not null एक नियम में अनुवाद किया जा सकता है और कहा: मैं जो एक राशि सभी पंक्तियों चाहते तारीख।

तो फिर तुम सबसे निश्चित रूप से यह कर सकते हैं: जहां mydatecolumn < = sysdate (ओरेकल में)

यह एक तारीख के साथ सभी पंक्तियों को वापस और शून्य मान ommit जबकि किसी भी का उपयोग किए बिना उस स्तंभ पर सूचकांक का लाभ लेने जाएगा संकेत।

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