I have a table with several million records in a PostgreSQL 12 database, and after an upgrade from 11 to 12, a few queries started performing horribly. They went from taking ~1 second to ~5 minutes. I tried rebuilding all indexes, vacuuming, and all usual Postgres low-hanging fruit, but performance is still terrible.
This is the query:
SELECT id, activity_count
FROM user
WHERE (search_index) @@ (to_tsquery('pg_catalog.english', '''1234567890'':*') AND active = true
ORDER BY activity_count DESC LIMIT 101
In other words, find all active users matching the given account number, and sort from most active to least.
This query takes about 5 minutes to return just 2 records. Something's not right.
The column search_index is a tsvector storing all the keywords from the table's various text fields (just things like account_number, name, etc).
I have a GIN index created for this column with:
CREATE INDEX user_search_index_gin
ON public.user USING gin
(search_index)
TABLESPACE pg_default;
I also have an index for the active column with:
CREATE INDEX user_active
ON public.user USING btree
(active ASC NULLS LAST)
TABLESPACE pg_default;
And I have an orderd index for the activity_count with:
CREATE INDEX user_activity_count
ON public.user USING btree
(activity_count ASC NULLS LAST)
TABLESPACE pg_default;
Yet when I run EXPLAIN, I get:
"Limit (cost=0.56..11443.66 rows=101 width=1552)"
" -> Index Scan Backward using user_activity_count on user (cost=0.56..36010185.91 rows=317836 width=1552)"
" Filter: (active AND (search_index @@ '''1234567890'':*'::tsquery))"
Why is it only using the user_activity_count index and not the more efficient GIN index? How do I fix this?