我的 PostgreSQL 9.3 数据库中有 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亿,需要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)
有没有提高性能的好方法,还是做表分区的好计划?