3

Ich habe 300 Millionen Adressen in meiner PostgreSQL 9.3 DB und ich möchte pg_trgm zur unscharfen Suche in den Zeilen verwenden. Der letztendliche Zweck besteht darin, eine Suchfunktion wie Google Map Search zu implementieren.Suche in 300 Millionen Adressen mit pg_trgm

Wenn ich pg_trgm verwendet, um diese Adressen zu suchen, kostet es ungefähr 30s, um die Ergebnisse zu erhalten. Es gibt viele Zeilen, die der Standard-Ähnlichkeitsschwellenwertbedingung von 0,3 entsprechen, aber ich brauche nur 5 oder 10 Ergebnisse. Ich habe einen trigram GiST Index:

CREATE INDEX addresses_trgm_index ON addresses USING gist (address gist_trgm_ops); 

Dies ist meine Frage:

SELECT address, similarity(address, '981 maun st') AS sml 
FROM addresses 
WHERE address % '981 maun st' 
ORDER BY sml DESC 
LIMIT 10; 

Die Testtabelle auf Produktionsumgebung entfernt wurde. Ich zeige die EXPLAIN Ausgabe von meiner Testumgebung. Es gibt ungefähr 7 Millionen Zeilen und es braucht ungefähr 1.6s, um Ergebnisse zu erhalten. Mit 300 Millionen benötigt es mehr als 30s.

ebdb=> explain analyse select address, similarity(address, '781 maun st') as sml from addresses where address % '781 maun st' order by sml desc limit 10; 
            QUERY PLAN                    
————————————————————————————————————————————————————————————————————————————————  
Limit (cost=7615.83..7615.86 rows=10 width=16) (actual time=1661.004..1661.010 rows=10 loops=1) 
-> Sort (cost=7615.83..7634.00 rows=7268 width=16) (actual time=1661.003..1661.005 rows=10 loops=1) 
    Sort Key: (similarity((address)::text, '781 maun st'::text)) 
    Sort Method: top-N heapsort Memory: 25kB 
    -> Index Scan using addresses_trgm_index on addresses (cost=0.41..7458.78 rows=7268 width=16) (actual time=0.659..1656.386 rows=5241 loops=1) 
      Index Cond: ((address)::text % '781 maun st'::text) 
Total runtime: 1661.066 ms 
(7 rows) 

Gibt es eine gute Möglichkeit, die Leistung zu verbessern, oder ist es ein guter Plan, Tabellenpartitionierung durchzuführen?

+1

"... ich brauche nur etwa 5 oder 10 Ergebnisse" ... setzen Sie ein passendes LIMIT auf die Abfrage? –

+0

Die Partitionierung ist in Postgres 9.3 verfügbar, wird jedoch mithilfe der Tabellenvererbung implementiert. Es ist explizit in Postgres 10 verfügbar. – Mokadillion

+0

Ich nehme an "300MM +" bedeutet 300 Millionen? Wenn ja, sollten Sie ElasticSearch oder etwas Ähnliches in Betracht ziehen. –

Antwort

1

PostgreSQL 9.3 ... Gibt es eine gute Möglichkeit, die Leistung zu verbessern, oder ist es ein guter Plan, Tabellenpartitionierung durchzuführen?

Tabelle Partitionierung wird nicht helfen überhaupt.

Aber ja, es gibt einen guten Weg: Upgrade auf eine aktuelle Version von Postgres. Es gibt viele Verbesserungen für GiST-Indizes, insbesondere für das Modul pg_trgm und allgemein für Big Data. Sollte mit Postgres 9.6 oder den kommenden Postgres 10 (derzeit Beta) wesentlich schneller sein.

You „nächster Nachbar“ sieht richtig, aber für eine kleine LIMIT diese äquivalente Abfrage verwenden statt:

SELECT address, similarity(address, '981 maun st') AS sml 
FROM addresses 
WHERE address % '981 maun st' 
ORDER BY address <-> '981 maun st' 
LIMIT 10;

Quoting the manual:

Es wird in der Regel die erste Formulierung schlagen, wenn nur eine geringe Anzahl von die engsten Übereinstimmungen sind erwünscht.

Verwandte Themen