我正在尝试针对primary_entity_name
搜索大约1000万行。但是,每次fq
有空格时,查询都会超时。
// "dog" works
// "walking dog" times out
select *
from companies
where primary_entity_name LIKE '%walking dog%'
limit 10
解释(分析,缓冲)
Limit (cost=0.00..21551.17 rows=10 width=1542) (actual time=52210.872..269801.658 rows=6 loops=1)
Buffers: shared hit=1429 read=2115468
-> Seq Scan on companies (cost=0.00..2247787.26 rows=1043 width=1542) (actual time=52210.871..269801.644 rows=6 loops=1)
Filter: ((primary_entity_name)::text ~~ '%walking dog%'::text)
Rows Removed by Filter: 10471215
Buffers: shared hit=1429 read=2115468
Planning time: 0.113 ms
Execution time: 269801.687 ms
查询计划
Limit (cost=0.00..41950.28 rows=10 width=1569)
-> Seq Scan on companies (cost=0.00..1959078.25 rows=467 width=1569)
Filter: ((primary_entity_name)::text ~~ '%walking dog%'::text)
答案 0 :(得分:0)
我认为用一个包含空格的搜索词来观察长持续时间只是巧合。尝试使用不同的字符串几次。
可能是搜索词的长度有一些影响,但该查询中压倒性的性能影响是I / O.
从执行计划中,您可以看到查询必须从磁盘读取大约16 GB并扫描1000万行以查找6个匹配的行。无论您的搜索模式是什么,只要以%
开头,该费用就会保持不变。
如果确实需要在字符串中间搜索字符串,您应该查看PostgreSQL的全文搜索功能,它完全解决了您在示例中显示的用例。如果你需要在单词的中间匹配字符串,事情会变得更难 - 你可能想看看pg_trgm
。