- Start each column tested with
=, in any order: INDEX(prefix, ...).
- Then move on to one range:
INDEX(prefix, date_updated, ...) or INDEX(prefix, end_date, ...). Include both; let the Optimizer discover which will be better.
- Finally, consider making the index "covering", as you did.
So, I recommend providing two composite, covering, indexes:
INDEX(prefix, date_updated, end_date, company_id)
INDEX(prefix, end_date, date_updated, company_id)
(Putting company_id first is not good -- it won't help with the WHERE, and barely helps with the "covering".)
More cases and discussion: http://mysql.rjweb.org/doc.php/index_cookbook_mysql
DISTINCT is a dedupping pass between WHERE and ORDER BY. (Also, DISTINCT is mostly redundant with GROUP BY.) DISTINCT and INDEX do interact, but not in your example.
Caveat: If you change anything in that query, my advice may be nullified.
prefixand the 2nd - eitherdate_updatedorend_date. Putcompany_idlast. how indexes work with DISTINCT Not used.