← All writing

Understand what a covering index can avoid

MySQL 8.0+ / InnoDBSources checked 2026-09-14

A list shows only an order ID and creation time for one tenant. If the chosen index contains every value needed by the query, MySQL may be able to answer from the index without fetching each full row. That is the idea behind a covering index.

Start from the actual projection

SELECT id, created_at
FROM orders
WHERE tenant_id = 42
ORDER BY created_at, id
LIMIT 50;

For an InnoDB table, secondary indexes also carry the primary key. The exact useful index depends on the primary key and existing schema. Inspect the plan rather than adding every selected column by reflex.

Covering has a write and storage cost

Adding wide text fields to an index just to cover one page can create a large index with poor maintenance characteristics. A small extra row lookup may be a better tradeoff. Changes to indexed values also require index updates.

The query can stop being covered when a later UI change adds a column. Keep performance-sensitive projections explicit so a harmless-looking SELECT * does not quietly change the access pattern.

Test with representative row counts and compare the complete workload, including writes if the table is frequently updated. Covering is one optimization technique, not the starting requirement for every query. Record which query the index serves and revisit it when the page's filters or sort order change.

Reference

Official documentation.