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

PostgreSQL के साथ समान स्ट्रिंग्स को शीघ्रता से ढूँढना

जिस तरह से आपके पास है, तालिका के प्रत्येक तत्व और हर दूसरे तत्व के बीच समानता की गणना की जानी चाहिए (लगभग एक क्रॉस जॉइन)। यदि आपकी तालिका में 1000 पंक्तियाँ हैं, तो पहले ., यह पहले से ही 1,00,000 (!) समानता गणना है उन्हें हालत के खिलाफ जांचा जा सकता है और क्रमबद्ध किया जा सकता है। बहुत तराजू।

SET pg_trgm.similarity_threshold . का उपयोग करें और % इसके बजाय ऑपरेटर। दोनों pg_trgm . द्वारा प्रदान किए गए हैं मापांक। इस तरह, एक ट्राइग्राम जीआईएसटी इंडेक्स का बहुत प्रभाव के लिए उपयोग किया जा सकता है।

कॉन्फ़िगरेशन पैरामीटर pg_trgm.similarity_threshold कार्यों को बदल दिया set_limit() और show_limit() पोस्टग्रेज 9.6 में। पदावनत कार्य अभी भी काम करते हैं (पोस्टग्रेज 13 के अनुसार)। साथ ही, पोस्टग्रेज 9.1 के बाद से GIN और GiST इंडेक्स के प्रदर्शन में कई तरह से सुधार हुआ है।

इसके बजाय प्रयास करें:

SET pg_trgm.similarity_threshold = 0.8;  -- Postgres 9.6 or later
  
SELECT similarity(n1.name, n2.name) AS sim, n1.name, n2.name
FROM   names n1
JOIN   names n2 ON n1.name <> n2.name
               AND n1.name % n2.name
ORDER  BY sim DESC;

परिमाण के क्रम से तेज़, लेकिन फिर भी धीमा।

pg_trgm.similarity_threshold एक "अनुकूलित" विकल्प है, जिसे किसी अन्य विकल्प की तरह संभाला जा सकता है। देखें:

  • एक पैरामीटर पूछें (postgresql.conf सेटिंग) जैसे "max_connections"

हो सकता है कि आप पहले पूर्व शर्त (जैसे पहले अक्षरों का मिलान) जोड़कर संभावित जोड़ियों की संख्या सीमित करना चाहें क्रॉस जॉइनिंग (और समर्थन करता है कि एक मिलान कार्यात्मक सूचकांक के साथ)। क्रॉस जॉइन . का प्रदर्शन O(N²) . के साथ बिगड़ता है ।

यह काम नहीं करता क्योंकि आप आउटपुट कॉलम को WHERE . में नहीं देख सकते या HAVING खंड:

WHERE ... sim > 0.8

यह SQL मानक के अनुसार है (जिसे कुछ अन्य RDBMS द्वारा शिथिल रूप से नियंत्रित किया जाता है)। दूसरी ओर:

ORDER BY sim DESC

काम करता है क्योंकि आउटपुट कॉलम कर सकते हैं GROUP BY . में उपयोग किया जा सकता है और ORDER BY . देखें:

  • पोस्टग्रेएसक्यूएल का पुन:उपयोग गणना परिणाम चुनिंदा क्वेरी में होता है

टेस्ट केस

मैंने अपने दावों को सत्यापित करने के लिए अपने पुराने परीक्षण सर्वर पर एक त्वरित परीक्षण चलाया।
PostgreSQL 9.1.4. EXPLAIN ANALYZE . के साथ लिया गया समय (सर्वश्रेष्ठ 5) ।

CREATE TEMP table t AS 
SELECT some_col AS name FROM some_table LIMIT 1000;  -- real life test strings

GIN इंडेक्स के साथ परीक्षण का पहला दौर:

CREATE INDEX t_gin ON t USING gin(name gin_trgm_ops);  -- round1: with GIN index

जीआईएसटी सूचकांक के साथ परीक्षण का दूसरा दौर:

DROP INDEX t_gin;
CREATE INDEX t_gist ON t USING gist(name gist_trgm_ops);

नई क्वेरी:

SELECT set_limit(0.8);

SELECT similarity(n1.name, n2.name) AS sim, n1.name, n2.name
FROM   t n1
JOIN   t n2 ON n1.name <> n2.name
           AND n1.name % n2.name
ORDER  BY sim DESC;

GIN इंडेक्स इस्तेमाल किया गया, 64 हिट:कुल रनटाइम:484.022 ms
GIST इंडेक्स इस्तेमाल किया गया, 64 हिट:कुल रनटाइम:248.772 ms

पुरानी क्वेरी:

SELECT (similarity(n1.name, n2.name)) as sim, n1.name, n2.name
FROM   t n1, t n2
WHERE  n1.name != n2.name
AND    similarity(n1.name, n2.name) > 0.8
ORDER  BY sim DESC;

GIN अनुक्रमणिका नहीं प्रयुक्त, 64 हिट:कुल रनटाइम:6345.833 ms
GIST अनुक्रमणिका नहीं इस्तेमाल किया गया, 64 हिट:कुल रनटाइम:6335.975 एमएस

अन्यथा समान परिणाम। सलाह अच्छी है। और यह सिर्फ 1000 पंक्तियों . के लिए है !

GIN या GiST?

GIN अक्सर बेहतर पठन प्रदर्शन प्रदान करता है:

  • जीआईएसटी और जीआईएन इंडेक्स के बीच अंतर

लेकिन इस विशेष मामले में नहीं!

<ब्लॉककोट>

इसे जीआईएसटी इंडेक्स द्वारा काफी कुशलता से लागू किया जा सकता है, लेकिन जीआईएन इंडेक्स द्वारा नहीं।

  • विषम डेटा प्रकारों के साथ 3 फ़ील्ड पर बहु-स्तंभ अनुक्रमणिका



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PgAdmin4 चलाने का प्रयास करने में त्रुटि

  2. मैं जावा का उपयोग करके PostgreSQL डेटाबेस में मौजूदा डेटाबेस से नई XML फ़ाइल कैसे बना सकता हूं?

  3. पोस्टग्रेस्क्ल LIKE क्वेरी पर जाएं

  4. PostgreSQL में GROUP BY और COUNT

  5. मैं PostgreSQL में अस्थायी रूप से ट्रिगर्स को कैसे अक्षम कर सकता हूं?