You added an index. The query is still slow. Before you add another one, find out why the planner is ignoring the first.
Start with EXPLAIN
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE lower(email) = 'a@b.co';
If you see Seq Scan, keep reading.
1. The query wraps the column in a function
An index on email cannot help lower(email). Either index the expression or store the value already lowered.
2. The types do not match
Comparing a text column to a number makes Postgres cast every row. Cast the parameter instead.
3. The planner thinks a scan is cheaper
On a small table, or when most rows match, reading everything is genuinely faster. Check the row estimates against reality.
4. The statistics are stale
After a big import, run ANALYZE on the table so the planner knows what it is dealing with.
