我有一个PostgreSQL 9.3数据库,其中包含3亿个地址。我想使用pg_trgm模糊搜索这些行,最终目的是实现类似Google地图搜索的搜索功能。
当我使用pg_trgm搜索这些地址时,需要大约30秒才能获取结果。虽然有许多行与默认相似度阈值条件0.3匹配,但我只需要大约5到10个结果。因此我创建了一个三元组GiST索引:
这是我的查询:
当我使用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)
有没有一种好的方法来提高性能,或者进行表分区是一个好计划吗?
explain (analyze, verbose)
**生成的执行计划。请使用格式化文本,不要使用屏幕截图。 - user330315