我在PostgreSQL 9.3數據庫中有3億個地址,我想用pg_trgm來模糊搜索行。最終目的是像谷歌地圖搜索一樣實施搜索功能。在3億個地址中搜索pg_trgm
當我使用pg_trgm搜索這些地址時,花費大約30秒才能得到結果。有很多行匹配0.3的默認相似性閾值條件,但我只需要大約5或10個結果。我創建了一個卦的GiST索引:
CREATE INDEX addresses_trgm_index ON addresses USING gist (address gist_trgm_ops);
這是我的查詢:
SELECT address, similarity(address, '981 maun st') AS sml
FROM addresses
WHERE address % '981 maun st'
ORDER BY sml DESC
LIMIT 10;
對生產環境的測試表已被刪除。我顯示了我測試環境下的EXPLAIN
輸出。大約有700萬行,需要大約1.6秒才能得到結果。有3億,需要30多個。
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)
有沒有一種很好的方法來提高性能,或者它是一個很好的計劃做表分區?
「...我只需要大約5或10個結果」...你是否在查詢中放置了一個合適的LIMIT? –
分區在Postgres 9.3中可用,但是使用表繼承來實現。它在postgres 10中明確提供。 – Mokadillion
我認爲「300MM +」意味着3億?如果是這樣,你應該考慮使用ElasticSearch或類似的東西。 –