2015-01-15 5 views
6

मैं डेटाबेस के लिए काफी नया हूं, और कुछ उच्च स्तर की सलाह ढूंढ रहा हूं।पोस्टग्रेस बड़े टेक्स्ट खोज सलाह

स्थिति
मैं एक डेटाबेस Postgres 9.3 का उपयोग कर, डेटाबेस के भीतर निर्माण कर रहा हूँ एक मेज जिसमें मैं लोग इन फ़ाइलों को स्टोर है।

CREATE TABLE errorlogs (
    id SERIAL PRIMARY KEY, 
    archive_id INTEGER NOT NULL REFERENCES archives, 
    filename VARCHAR(256) NOT NULL, 
    content TEXT); 

सामग्री में पाठ 1k से 50MB के लिए कहीं भी लंबाई में भिन्न हो सकते हैं।

समस्या
मैं "सामग्री" स्तंभ के भीतर डेटा पर यथोचित तेज लेख वाली खोजें करने के लिए सक्षम होना चाहते हैं (उदाहरण के लिए, जहां सामग्री की तरह '% some_error%')। अभी खोज बहुत धीमी हैं (> 8206 पंक्तियों के माध्यम से खोजने के लिए 10 मिनट)।

मुझे पता है कि इंडेक्सिंग का उद्देश्य मेरी समस्या का समाधान होना है, लेकिन मुझे लगता है कि मैं इंडेक्स बनाने में सक्षम नहीं हूं - जब भी मैं कोशिश करता हूं तो मुझे त्रुटियां मिलती हैं कि सूचकांक बहुत बड़ा होगा।

=# CREATE INDEX error_logs_content_idx ON errorlogs (content text_pattern_ops);
ERROR: index row requires 1796232 bytes, maximum size is 8191

मैं इस समस्या को हल करने के बारे में कुछ सलाह लेने की उम्मीद कर रहा था। क्या मैं अधिकतम इंडेक्स आकार बदल सकता हूं? या क्या मुझे टेक्स्ट फ़ील्ड पर पूर्ण टेक्स्ट खोज के लिए पोस्टग्रेस का उपयोग करने की कोशिश नहीं करनी चाहिए?

कोई सलाह बहुत सराहना की है!

+2

की तरह मुझे लगता है कि आप शायद पूर्ण-पाठ खोज/अनुक्रमण http://www.postgresql.org/docs/9.1/static/textsearch-intro.html लिए देख रहे हैं करना चाहते हैं। –

+1

यह उत्तर भी मदद कर सकता है, http://stackoverflow.com/questions/1566717/postgresql-like-query-performance-variations/13452528#13452528 –

+0

हाय जॉन, सलाह के लिए धन्यवाद। मैं पहले से ही टेक्स्ट्सशर्च दस्तावेज़ों से गुजर चुका हूं, और मुझे इंडेक्स सीमाओं पर कोई जानकारी नहीं मिली।आपके द्वारा पोस्ट की गई दूसरी टिप्पणी में टेक्स्ट_पर्टर्न_ओप्स इंडेक्स बनाने का वर्णन किया गया है, जैसा कि मैंने ऊपर बताया है, इंडेक्स के बारे में एक त्रुटि बहुत बड़ी है। – JBeFat

उत्तर

2

टेक्स्ट सर्च वेक्टर डेटा को इस बड़े पैमाने पर संभाल नहीं सकते --- documented limits देखें। उनकी ताकत अस्पष्ट खोज है, इसलिए आप उसी कॉल में 'तैरना' और 'तैरना', 'तैराकी,' 'तैराकी' और 'तैर' ढूंढ सकते हैं। वे grep को प्रतिस्थापित करने के लिए नहीं हैं।

सीमाओं का कारण source code MAXSTRLEN (और MAXSTRPOS) के रूप में है। टेक्स्ट सर्च वेक्टर एक लंबे, निरंतर सरणी में 1 एमआईबी तक लम्बाई में रखे जाते हैं (सभी अद्वितीय लेक्सम के लिए सभी पात्रों की कुल)। इन तक पहुंचने के लिए, ts_vector अनुक्रमणिका संरचना शब्द लंबाई के लिए 11 बिट्स और सरणी में अपनी स्थिति के लिए 20 बिट्स की अनुमति देती है। ये सीमाएं इंडेक्स संरचना को 32-बिट हस्ताक्षरित int में फिट करने की अनुमति देती हैं।

यदि आप फ़ाइल में बहुत से अनूठे शब्द हैं या शब्दों को बार-बार दोहराया जाता है --- यदि आपके पास अर्ध-यादृच्छिक डेटा के साथ 50 एमबी लॉग फ़ाइल है तो आप शायद इन दोनों सीमाओं में भाग ले रहे हैं।

क्या आप वाकई डेटाबेस में लॉग फ़ाइलों को स्टोर करने की आवश्यकता है? आप मूल रूप से फ़ाइल सिस्टम की प्रतिलिपि बना रहे हैं, और grep या python वहां काफी अच्छी तरह से खोज कर सकते हैं। यहाँ

CREATE TABLE errorlogs (
    id SERIAL PRIMARY KEY 
    , archive_id INTEGER NOT NULL REFERENCES archives 
    , filename VARCHAR(256) NOT NULL 
); 

CREATE TABLE log_lines (
    line PRIMARY KEY 
    , errorlog INTEGER REFERENCES errorlogs(id) 
    , context TEXT 
    , tsv TSVECTOR 
); 

CREATE INDEX log_lines_tsv_idx ON log_lines USING gin(line_tsv); 

, आप प्रत्येक लॉग ऑन लाइन एक के रूप में इलाज: तुम सच में की जरूरत है, हालांकि, तो आप इस पर विचार हो सकता "दस्तावेज़।" खोजने के लिए, आप कुछ

SELECT e.id, e.filename, g.line, g.context 
FROM errorlogs e JOIN log_lines g ON e.id = g.errorlog 
WHERE g.tsv @@ to_tsquery('some & error'); 
+0

सुझाव के लिए बहुत बहुत धन्यवाद। मैंने प्रति पंक्ति एक एकल लॉग लाइन को संग्रहीत करने के लिए स्विच किया है। मैंने अभी तक अनुक्रमण की कोशिश नहीं की है - बस कोशिश की और यह अच्छी तरह से काम करता है। एक बार फिर धन्यवाद! – JBeFat