मुझे उम्मीद है बहुत इस दृष्टिकोण के साथ तेज़ परिणाम:
1.
1 कॉलम के साथ एक जीआईएसटी इंडेक्स बनाएं जिसमें कॉन्टेनेटेड वैल्यू हों:
CREATE INDEX users_search_idx ON auth_user
USING gist((username || ' ' || first_name || ' ' || last_name) gist_trgm_ops);
यह मानता है कि सभी 3 कॉलम परिभाषित किए गए हैं NOT NULL
(आपने निर्दिष्ट नहीं किया)। नहीं तो आपको और अधिक करने की आवश्यकता है।
क्यों न concat_ws()
के साथ सरल बनाया जाए ?
- दो कॉलमों को मिलाएं और एक नए कॉलम में जोड़ें
- एकाधिक टेक्स्ट फ़ील्ड पर पैटर्न-मिलान के साथ तेज़ क्वेरी
- दो कॉलमों को मिलाएं और एक नए कॉलम में जोड़ें
2.
एक उचित निकटतम-पड़ोसी का उपयोग करें क्वेरी, इंडेक्स के ऊपर मिलान:
SELECT username, email, first_name, last_name
, similarity(username , $1) AS s_username
, similarity(first_name, $1) AS s_first_name
, similarity(last_name , $1) AS s_last_name
, row_number() OVER () AS rank -- greatest similarity first
FROM auth_user
WHERE (username || ' ' || first_name || ' ' || last_name) % $1 -- !!
ORDER BY (username || ' ' || first_name || ' ' || last_name) <-> $1 -- !!
LIMIT $2;
WHERE
में भाव और ORDER BY
इंडेक्स एक्सप्रेशन से मेल खाना चाहिए!
विशेष रूप से ORDER BY rank
(जैसे आपके पास था) हमेशा एक छोटे से LIMIT
. के लिए खराब प्रदर्शन करेगा क्वालिफाइंग पंक्तियों के बहुत बड़े पूल से चुनना, क्योंकि यह सीधे एक इंडेक्स का उपयोग नहीं कर सकता:rank
के पीछे परिष्कृत अभिव्यक्ति प्रत्येक . के लिए गणना की जानी है क्वालीफाइंग पंक्ति, फिर सभी को सर्वश्रेष्ठ मैचों के छोटे चयन को वापस करने से पहले क्रमबद्ध करना होगा। यह काफी, कहीं अधिक महंगा . है एक वास्तविक निकटतम-पड़ोसी क्वेरी की तुलना में जो बाकी को देखे बिना सीधे इंडेक्स से सर्वोत्तम परिणाम चुन सकती है।
row_number()
खाली विंडो परिभाषा के साथ केवल ORDER BY
. द्वारा उत्पादित क्रम को दर्शाता है उसी का SELECT
।
संबंधित उत्तर:
आपके आइटम के लिए 3.
, मैंने आपके द्वारा संदर्भित प्रश्न का उत्तर जोड़ा है, जो इसे स्पष्ट करना चाहिए: