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?
"... ich brauche nur etwa 5 oder 10 Ergebnisse" ... setzen Sie ein passendes LIMIT auf die Abfrage? –
Die Partitionierung ist in Postgres 9.3 verfügbar, wird jedoch mithilfe der Tabellenvererbung implementiert. Es ist explizit in Postgres 10 verfügbar. – Mokadillion
Ich nehme an "300MM +" bedeutet 300 Millionen? Wenn ja, sollten Sie ElasticSearch oder etwas Ähnliches in Betracht ziehen. –