我有一个包含 200k 元组的 Postgresql 表,所以没有那么多。我尝试做的是过滤掉一些行,然后使用全文匹配对它们进行排序:
SELECT * FROM descriptions as d
WHERE d.category_id = ?
AND d.description != ''
AND regexp_replace(d.description, '(...)', '') !~* '...'
AND regexp_replace(d.description, '...', '') !~* '...'
AND d.id != ?
ORDER BY ts_rank_cd(to_tsvector('english', name), plainto_tsquery('english', 'my search words')) DESC LIMIT 5 OFFSET 0';
描述字段上有一个 GIN 索引。
现在此查询仅在类别中的记录少于 4000 条左右时才能正常工作。当它更像 5k 或 6k 时,查询会变得非常慢。
我正在尝试这个查询的不同变体。我注意到的是,当我删除 WHERE 子句或 ORDER BY 子句时,我的速度会大大提高。(当然,我得到不相关的结果)
我能做些什么来加速这种组合?任何优化方式还是我应该在 Postgresql 之外寻找解决方案?
附加问题:
我正在进一步试验,例如这是我认为运行速度太慢的最简单查询。我可以从解释分析中看出它何时使用 gist 索引,何时不使用?
SELECT d.*, d.description <-> 'banana' as dist FROM descriptions as d ORDER BY dist DESC LIMIT 5
"Limit (cost=16046.88..16046.89 rows=5 width=2425) (actual time=998.811..998.813 rows=5 loops=1)"
" -> Sort (cost=16046.88..16561.90 rows=206010 width=2425) (actual time=998.810..998.810 rows=5 loops=1)"
" Sort Key: (((description)::text <-> 'banana'::text))"
" Sort Method: top-N heapsort Memory: 27kB"
" -> Seq Scan on products d (cost=0.00..12625.12 rows=206010 width=2425) (actual time=0.033..901.260 rows=206010 loops=1)"
"Total runtime: 998.866 ms"`
已回答 (kgrittn): DESC 关键字对于 KNN-GiST 不正确,实际上这里不需要它。删除它可以解决问题并给出正确的结果。