sql - ओरेकल 12c-'varchar' कॉलम पर सूचकांक की तुलना में तेजी से प्रदर्शित 'नंबर' कॉलम पर सूचकांक है?




oracle indexing numbers (2)

मान लें कि मेरे पास ओरेकल 12 सी में कॉलम के साथ एक टेबल है:

create table t1 (
a number (5,0),
b varchar (5,0)
d ...
e ...
);

फिर मैं दोनों कॉलम में 100,000,000 रिकॉर्ड डालने के लिए एक ही मूल्य है - जैसे

20151 and '20152' ... (for a first record)
20152 and '20152' ... (for a second record)
20153 and '20153' ... (for a third record)
...

फिर मैं स्तंभ 'a' पर सूचकांक 1 और स्तंभ 'b'. पर 2 सूचकांक जोड़ता हूं

प्रश्न - कॉलम 'a' पर कॉलम 'b' 'a' रूप में कॉलम 'b' खिलाफ निष्पादित करते समय प्रश्न समान रूप से तेज़ी से प्रदर्शित होता है (जैसे कॉलम 'b' पर आधारित किसी अन्य तालिका के साथ प्रश्न पूछें या कॉलम 'b' या डब्ल्यूएचईईई के आधार पर या तो कॉलम)?

इसके अलावा - एक ' varchar ' कॉलम पर सूचकांक का उपयोग करना होगा - 'नंबर' कॉलम पर अनुक्रमणिका का उपयोग करने से ज्यादा सीपीयू का उपयोग करें?

धन्यवाद।


Answers

[टीएल; डीआर] तारों को स्टोर करने के लिए तिथियों, संख्याओं को स्टोर करने के लिए संख्याओं और तारों को स्टोर करने के लिए तिथियों का उपयोग करें।

संसाधन उपयोग के बारे में कैसे?

ओरेकल NUMBER डेटा प्रकार को 1 बाइट प्रति 2 अंकों के रूप में संग्रहीत करता है।

ओरेकल CHAR डेटा प्रकार को 1 बाइट प्रति एएससीआईआई वर्ण (यूटीएफ -8 और अन्य एन्कोडिंग विस्तारित सेटों में वर्णों के लिए अधिक ले सकते हैं) के रूप में भंडारित करता है और स्ट्रिंग्स के साथ स्ट्रिंग पैड को सही करेंगे ताकि स्ट्रिंग्स बिल्कुल समान लंबाई हो।

ओरेकल VARCHAR2 डेटा प्रकार को 1 बाइट प्रति एएससीआईआई वर्ण के साथ-साथ स्ट्रिंग लम्बाई के लिए एक छोटे से ओवरहेड (1 या 2 बाइट्स) स्टोर करता है।

ओरेकल DATE डेटा प्रकार को 7 बाइट्स (वर्ष के लिए 2 और प्रत्येक माह, दिन, घंटा, मिनट, सेकंड के लिए 1) के रूप में संग्रहीत करता है।

आपके पिछले प्रश्न के आधार पर आप year और quarter भंडारण में आते हैं और मानते हैं कि आप हमेशा 4-अंक वर्ष और 1-अंकों के क्वार्टर के साथ जा रहे हैं:

  • NUMBER(5,0) 3 बाइट्स लेंगे;
  • CHAR(5 CHARACTER) 5 बाइट्स लेंगे;
  • VARCHAR2(5 CHARACTER) 6 बाइट्स लेंगे; तथा
  • DATE को 7 बाइट्स लगेगा।

इसलिए केवल स्मृति पर विचार करना एक NUMBER(5,0) सबसे कुशल होगा

तथापि

जैसे ही आप संख्या / तारों के रूप में संग्रहीत वर्ष / तिमाहियों पर अंकगणित करना शुरू करते हैं, तब आप प्रदर्शन समस्याओं में आ जाते हैं:

उदाहरण के लिए, अगली तिमाही प्राप्त करना:

  • अगर quarter एक NUMBER डेटा प्रकार है तो आप इसका इस्तेमाल कर सकते हैं: CASE WHEN MOD(quarter,10) = 4 THEN quarter + 7 ELSE quarter + 1 END लेकिन जब आप 5 क्वार्टर जोड़ना चाहते हैं या फिर क्वार्टर घटाकर शुरू करना चाहते हैं तर्क अधिक जटिल हो जाना शुरू होता है
  • अगर quarter एक CHAR डेटा प्रकार है तो आप इसे किसी नंबर या डेट में बदल सकते हैं और उन विधियों में से किसी एक का उपयोग कर सकते हैं (स्ट्रिंग हेरफेर प्रदर्शनकारी होने की संभावना नहीं है)।
  • अगर quarter एक DATE तो आपको सिर्फ ADD_MONTHS( quarter, 3 ) का उपयोग करने की आवश्यकता है।

DATE विधि स्व-दस्तावेजी है और पहले से मौजूद है, जबकि NUMBER विधि सिर्फ आपके QUARTER डेटा प्रकार के सन्निकटन के लिए एक कस्टम फ़ंक्शन बन जाएगी और जब आप सभी तुलनात्मक और हेरफेर कार्यों को लागू करेंगे, तो आप प्रभावी रूप से DATE डाटा प्रकार को पुनः लिखेंगे क्वार्टरों के लिए एक यूडीटी और उन कार्यों को अनुकूलित डेट फ़ंक्शन से कम प्रतिफल होगा।

अनुपयुक्त डेटा प्रकारों का उपयोग न करें - बस तारीखों को तिथियों के रूप में स्टोर करें; नंबरों की संख्या; और स्ट्रिंग स्ट्रिंग के रूप में।


एक चुनिंदा क्वेरी चलाने से पहले, इसे चलाएं:

SET SERVEROUT ON SIZE 6000

SELECT XMLAGG(XMLELEMENT(E,SUPLR_SUPLR_ID||',')).EXTRACT('//text()') "SUPPLIER" 
FROM SUPPLIERS;




sql oracle indexing numbers