2012-08-25 8 views
6

मैं परीक्षण की संख्या के साथ एक प्रश्न है कुछ इस तरह-प्रांगण:Postgresql iLike बनाम TSEARCH

SELECT * FROM some-table 
    WHERE field1 ILIKE "%thing%" 
    OR field2 ILIKE "%thing" 
    OR field3 ILIKE "%thing"; 

कॉलम काफी सभी varchar (50) या आस कर रहे हैं। अब मैं प्रदर्शन में सुधार करने के लिए समझता हूं, मुझे उन फ़ील्ड को इंडेक्स करना चाहिए जिन पर खोज चलती है। क्या मुझे पूरी तरह से TSEARCH के साथ ILIKE को बदलने पर विचार करना चाहिए?

उत्तर

15

एक पूर्ण पाठ खोज सेटअप क्वेरी जैसे "शामिल" के समान नहीं है। यह शब्द आदि उत्पन्न करता है ताकि आप "कार" के खिलाफ "कार" से मेल खा सकें।

यदि आप वास्तव में एक तेज ILIKE चाहते हैं तो कोई मानक डेटाबेस इंडेक्स या एफटीएस मदद नहीं करेगा। सौभाग्य से, pg_trgm मॉड्यूल ऐसा कर सकता है।

+0

pg_trgm बहुत उपयोगी है। Django उपयोगकर्ताओं के लिए: 'ऊपरी (your_text_field) पर सूचकांक' क्योंकि Django 'ilike' के बजाय ऊपरी (y)' क्वेरी की तरह ऊपरी (x) को जारी करता है। यदि फ़ील्ड को 'ऊपरी' के बिना अनुक्रमित किया गया है तो इंडेक्स उन प्रश्नों में उपयोग नहीं किया जाएगा। – Risadinha

5

एक बात है कि बहुत महत्वपूर्ण है: सं बी वृक्ष सूचकांक कभी खोज के इस प्रकार में सुधार होगा:

where field ilike '%SOMETHING%' 

क्या मैं कह रहा हूँ यह है कि आप एक करते हैं:

create index idx_name on some_table(field); 

एकमात्र एक्सेस जो आप सुधारेंगे where field like 'something%' है। (जब आप कुछ शाब्दिक से शुरू मूल्यों की खोज करते हैं)। इसलिए, इस मामले में field कॉलम में नियमित अनुक्रमणिका जोड़कर आपको कोई लाभ नहीं मिलेगा।

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

+0

आप सही हैं कि कोई भी बी-ट्री उस खोज को बेहतर नहीं करेगा, लेकिन पोस्टग्रेएसक्यूएल '% foobar% 'स्थिति (रिचर्ड का जवाब देखें) का समर्थन करने के लिए अन्य इंडेक्स प्रकारों का उपयोग कर सकता है –

3

सबसे पहले आप वास्तव में स्ट्रिंग के बीच में किसी मान के आधार पर एक अनुक्रमणिका का उपयोग नहीं कर सकते हैं। इंडेक्स आमतौर पर वृक्ष खोज होते हैं, और आपके पास यह जानने का कोई तरीका नहीं है कि आपकी खोज तालिका को स्कैन करने से तेज होगी या नहीं, इसलिए PostgreSQL एक सीक स्कैन के लिए डिफ़ॉल्ट होगा। इंडेक्स का उपयोग केवल तभी किया जाएगा जब वे स्ट्रिंग के पहले भाग से मेल खाते हैं। तो:

SELECT * FROM invoice 
    WHERE invoice_number like 'INV-2012-435%' 

एक सूचकांक का उपयोग कर सकते हैं लेकिन like '%44354456%' नहीं कर सकता।

सामान्य रूप से लेजर एसएमबी में हम दोनों का उपयोग करते हैं, इस पर निर्भर करते हुए कि हम किस प्रकार की खोज कर रहे हैं। आपको एक खोज दिखाई दे सकती है:

select * from parts 
    WHERE partnumber ilike ? || '%' 
    and plainto_tsquery(get_default_language(), ?) @@ description; 

तो ये बहुत अलग हैं। प्रत्येक का प्रयोग करें जहां यह सबसे ज्यादा समझ में आता है।

+1

मैं मानता हूं कि यह सुनिश्चित करने के लिए पर्याप्त जानकारी नहीं है कि ट्राइग्राम या tsearch अधिक उपयुक्त है, लेकिन एक या दूसरे (या संभवतः एक संयोजन) संकेत मिलता है। – kgrittn