The selectivity paradox is the part worth remembering — the same GIN index was about 37% slower when the query matched a third of the table, then about 27% faster once the match narrowed to 11%. That, plus the Django syntax trap where metadata__plan never reaches the index while metadata__contains does, is exactly why the advice to verify with .explain() matters. An index isn't a speed guarantee; it's a tool that only pays off when the query, the operator, and the data distribution line up.
Steven Mock
Founder of MockTools
The selectivity paradox is the part worth remembering — the same GIN index was about 37% slower when the query matched a third of the table, then about 27% faster once the match narrowed to 11%. That, plus the Django syntax trap where metadata__plan never reaches the index while metadata__contains does, is exactly why the advice to verify with .explain() matters. An index isn't a speed guarantee; it's a tool that only pays off when the query, the operator, and the data distribution line up.