2012-06-04 13 views
9

मैं PostgreSQL पूर्ण पाठ खोज (pg_search मणि ​​का उपयोग करके) और solr (sunspot_solr मणि) के लिए प्रदर्शन का परीक्षण कर रहा हूं।उचित पूर्ण पाठ अनुक्रमणिका रेल/PostgreSQL/pg_search

4 लाख रिकॉर्ड के लिए मैं Tsearch के लिए 13456 एमएस और SOLR साथ 800 एमएस हो रही है (कि SOLR क्वेरी + डीबी retrival है)। यह स्पष्ट है कि मुझे इंडेक्स की आवश्यकता है लेकिन मुझे यकीन नहीं है कि पूर्ण पाठ खोज के लिए एक कैसे बनाया जाए। मैंने जांच की और पाया कि पूर्ण पाठ खोज के लिए मुझे जीआईएन इंडेक्स का उपयोग करना चाहिए।

execute "CREATE INDEX products_gin_title ON products USING GIN(to_tsvector('english', title))" 

लेकिन मैं दो और कॉलम के माध्यम से तलाश कर रहा हूँ और मैं बहु मूल्य सूचकांक की जरूरत है और मुझे यकीन है कि यह कैसे लागू करने के लिए नहीं कर रहा हूँ? मैं डीबी भाग से बहुत परिचित नहीं हूं। मेरे खोज कोड लगता है:

@results = Product.search_title(params[:search_term]).where("platform_id=? AND product_type=?", params[:platform_id], params[:type_id]).limit(10).all 

मैं कैसे स्थितियों के इस प्रकार के लिए उचित क्वेरी बना सकता हूँ?

यहां खोज शब्द कार के लिए रेल से एसक्यूएल आउटपुट है।

Product Load (12494.0ms) 
SELECT 
    "products".*, 
    (ts_rank((to_tsvector('simple', coalesce("products"."title"::text, ''))), (to_ tsquery('simple', ''' ' || 'car' || ' ''')), 2)) AS pg_search_rank 
FROM "products" 
WHERE (((to_tsvector('simple', coalesce("products"."tit le"::text, ''))) @@ (to_tsquery('simple', ''' ' || 'car' || ' ''')))) 
    AND (platform_id='26' AND product_type='2') 
ORDER BY pg_search_rank DESC, "products"."id" ASC 
LIMIT 10 

संपादित करें:

मैं PostgreSQL 8.4.11 उपयोग कर रहा हूँ, EXPLAIN ANALYZE उत्पादन पीछा कर रहा है।

Limit (cost=108126.34..108126.36 rows=10 width=3824) (actual time=12228.736..12228.738 rows=10 loops=1) 
-> Sort (cost=108126.34..108163.84 rows=14999 width=3824) (actual time=12228.733..12228.734 rows=10 loops=1) 
    Sort Key: (ts_rank(to_tsvector('simple'::regconfig, COALESCE((title)::text, ''::text)), '''car'''::tsquery, 2)), id 
    Sort Method: top-N heapsort Memory: 18kB 
    -> Seq Scan on products (cost=0.00..107802.22 rows=14999 width=3824) (actual time=7.532..12224.585 rows=977 loops=1) 
     Filter: ((platform_id = 26) AND (product_type = 2) AND (to_tsvector('simple'::regconfig, COALESCE((title)::text, ''::text)) @@ '''car'''::tsquery)) 

Total runtime: 12228.813 ms 
+0

कृपया पोस्ट क्वेरी पर 'एक्सप्लिन विश्लेषण' चलाने के आउटपुट को पोस्ट करें, साथ ही अपने पीजी संस्करण, आपके द्वारा बदला गया कोई पोस्टग्रेस्क्ल.कॉम पैराम्स इत्यादि। –

उत्तर

8

यह अभिव्यक्ति:

to_tsvector('simple', (COALESCE(title::TEXT), '')) 

अपने सूचकांक के खिलाफ sargable नहीं है।

आप वास्तव में अभिव्यक्ति जो क्वेरी में प्रयोग किया जाता है पर सूचकांक घोषित करना चाहिए:

CREATE INDEX products_gin_title 
ON products 
USING GIN(to_tsvector('simple', COALESCE(title::TEXT,''))) 

(या माणिक अभिव्यक्ति जो सूचकांक में प्रयोग किया जाता है उत्पन्न कर)।

एकाधिक कॉलम अनुक्रमित करने के लिए चाहते हैं, बस उन्हें श्रेणीबद्ध:

CREATE INDEX products_gin_title 
ON products 
USING GIN(to_tsvector('simple', title || ' ' || product_type || ' ' || platform_id)) 

लेकिन फिर से, रूबी सूचकांक के लिए ठीक उसी अभिव्यक्ति के आधार पर फ़िल्टर किया जाना चाहिए उपयोग की हो।

+0

धन्यवाद मुट्ठी एकल कॉलम इंडेक्स अब काम करता है क्वेरी समय 80 एमएस है, अच्छा! इसके अलावा आपके लिए प्रश्न यह है कि गति को और बढ़ाने के लिए यह बहु स्तंभ सूचकांक होना चाहिए? जब आप उन्हें संयोजित करते हैं, तो क्या इसका मतलब है कि मुझे अपने खोज शब्द में एफके आईडी को संयोजित करके पूर्ण पाठ खोज करना चाहिए? –

+0

@ डॉल्फिन: जो 'एफके आईडी' है? – Quassnoi

+0

इस उदाहरण में मैं पूर्ण पाठ के माध्यम से शीर्षक खोज रहा हूं, और product_type, platform_id (उल्लिखित एफके) के साथ परिणामों को भी सीमित कर रहा हूं। मैं इस धारणा के तहत हूं कि यदि आप विशिष्ट क्वेरी को तेज करना चाहते हैं तो आपको उस क्वेरी में उपयोग किए गए सभी कॉलम के लिए अनुक्रमणिका जोड़ने की आवश्यकता है। –

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