Marked as helpful by the asker
8 seconds for 2,000 rows is not the database, it's the app doing something per row. Open the network tab: I bet you see hundreds of requests. That's an N+1: the list loads, then each row fetches its own related data.
Fix it in one query with a join:
supabase.from('items').select('*, supplier(name)').eq('status', 'active').range(0, 49)And add an index on status while you're there:
create index items_status_idx on items (status);