EXPLAIN says what the optimiser chose. It does not say why, so when a perfectly good index is ignored there is nothing to read. The optimizer trace is the reasoning, including the cost it assigned to each option it rejected.
SET optimizer_trace = 'enabled=on';
SELECT * FROM orders WHERE customer_id = 91 AND status = 'paid';
SELECT TRACE FROM information_schema.OPTIMIZER_TRACEG
SET optimizer_trace = 'enabled=off';
The output is verbose JSON and the useful part is considered_execution_plans, which lists each access path with its estimated cost — so an index rejected because the optimiser believes it matches 40% of the table tells you the statistics are stale, not that the index is wrong. Enable it per session and turn it off afterwards; it is not free, and the buffer is capped so a complex query can truncate its own explanation.