私は 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 インデックスを使用する場合と使用しない場合は、Explain Analyst からわかりますか?
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 では正しくなく、実際にはここでは必要ありません。削除すると問題が修正され、正しい結果が得られます。