80% of indexes I see in production databases are useless or actively harmful. They were added because a query was slow, the developer guessed at a fix, the query got faster (or didn't), and nobody validated. The index sat there forever, slowing down every write.
PostgreSQL indexes are not free. Every insert, update, and delete has to update every index. A table with 10 indexes writes 11 rows on every insert. That's the trade — read speed for write speed.
Here's how I actually do it.
The single most important tool: EXPLAIN ANALYZE
Not EXPLAIN. EXPLAIN ANALYZE. The difference matters.
EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = '123';