PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL:यह क्वेरी मेरी अनुक्रमणिका का उपयोग क्यों नहीं कर रही है?

जैसा कि आप पहले ही महसूस कर चुके हैं, समस्या बराबर के अलावा अन्य ऑपरेटरों का उपयोग करने से संबंधित है। इंडेक्स का उपयोग केवल सबसे बाएं कॉलम के लिए सबसे अधिक कुशलता से किया जा सकता है, जिसकी तुलना बराबर (प्लस वन रेंज कंडीशन) से की जाती है।

आपके उदाहरण में:

create index i on t (a,b,c,d);
where a=1 and b=11 and c!=5 and d<8;

यह केवल a . के लिए अनुक्रमणिका का उपयोग कर सकता है और b कुशलता से। इसका मतलब है कि डीबी a . से मेल खाने वाली सभी पंक्तियों को प्राप्त करता है और b कंडीशन और फिर शेष स्थितियों के खिलाफ प्रत्येक पंक्ति की जांच करता है।

जब आप c . पर फ़िल्टर बदलते हैं बराबर करने के लिए, यह (संभावित रूप से) कम पंक्तियाँ प्राप्त करता है (केवल वे जो a . से मेल खाते हैं और b और c ) और फिर उन (कम) पंक्तियों को d . के विरुद्ध जांचता है छानना इस मामले में अनुक्रमणिका का उपयोग करना अधिक कुशल है।

सामान्य तौर पर, PostgreSQL क्वेरी प्लानर दोनों विकल्पों का मूल्यांकन करता है:(1) अनुक्रमणिका का उपयोग करके; (2) एक SeqScan कर रहा है। दोनों के लिए, यह एक लागत मूल्य की गणना करता है - यह जितना अधिक होगा, अपेक्षित प्रदर्शन उतना ही खराब होगा। नतीजतन, यह कम लागत मूल्य के साथ एक लेता है। इस तरह यह सूचकांक का उपयोग करने का निर्णय लेता है या नहीं, इसकी कोई निश्चित सीमा नहीं है।

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

इस बात को ध्यान में रखते हुए कि आपकी क्वेरी में आपकी एक ही श्रेणी की स्थिति है, मैं इस तरह के सूचकांक को बदलने का सुझाव दूंगा:

create index i on t (a,b,d,c);

अब यह a . पर फ़िल्टर का उपयोग कर सकता है और b और d सूचकांक के साथ कुशलतापूर्वक और केवल उन पंक्तियों को फ़िल्टर करने की आवश्यकता है जहां c!=5 . यद्यपि यह अनुक्रमणिका आपकी मूल क्वेरी के रूप में आपकी क्वेरी के लिए अधिक कुशलता से उपयोग की जा सकती है, इसका स्वचालित अर्थ यह नहीं है कि PG इसका उपयोग करेगा। यह लागत अनुमानों पर निर्भर करता है। लेकिन इसे आजमाएं।

अंत में, यदि यह पर्याप्त तेज़ नहीं है और मान 5 आप अभिव्यक्ति में प्रयोग कर रहे हैं c!=5 स्थिर है, आप एक आंशिक अनुक्रमणिका पर विचार कर सकते हैं:

 create index i on t (a,b,d)
        where c!=5;

आप अन्य सभी स्तंभों के साथ भी ऐसा कर सकते हैं, यदि आप जिन मूल्यों से उनकी तुलना करते हैं वे स्थिरांक हैं।

संदर्भ:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. अगले रैंक (Postgresql) के LAG () / LEAD ()

  2. EF6 + पोस्टग्रेज संबंध dbo.AspNetUsers मौजूद नहीं है

  3. केवल नई पंक्तियों के लिए डिफ़ॉल्ट नाउ () के साथ टाइमस्टैम्प कॉलम जोड़ें

  4. विभिन्न डेटाबेस से तालिकाओं में शामिल हों (PostgreSQL)

  5. Python में SSH टनलिंग के माध्यम से PostgreSQL डेटाबेस से कनेक्ट करना