The covering index that removed a filesort

An index containing every column the query touches means the table is never read, and the plan says Using index.

-- before: idx (status), then a lookup per row, then a sort
SELECT id, customer_id, total_cents FROM orders
WHERE status = 'pending' ORDER BY created_at DESC LIMIT 20;
-- Using where; Using filesort   — 180ms

ALTER TABLE orders ADD INDEX idx_covering
  (status, created_at, id, customer_id, total_cents);
-- Using index    — 3ms

The column order is the design: equality predicates first, then the sort column, then the payload. Adding the payload columns is what makes it covering and it is also what makes the index large — this one is 140 MB, which is a real cost on write and on buffer pool. Covering indexes are worth it for a query that runs constantly and not for one that runs nightly.