Why is MySQL performing a filesort on this query? I'm expecting simply Using where:
SELECT * FROM active_campaign_days
WHERE ad_unit_id=1
AND day='2017-12-10'
ORDER BY bid DESC, budget DESC, campaign_id ASC
Index on (ad_unit_id, day, bid, budget, campaign_id) - the database is using this index according to the EXPLAIN.
In this particular result set, bid and budget are the same for all rows. (ad_unit_id, campaign_id) is unique.
EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE active_campaign_days ref ad_unit_id,ad_unit_id_2 ad_unit_id_2 7 const,const 5 Using where; Using filesort
Let's dissect the query..
The
WHERE ad_unit_id=1 AND day='2017-12-10'needs an index starting withad_unit_idandday(in either order). This will provide optimal filtering.If practical, all the
ORDER BYcan be added to thatINDEXso that it can avoid having to sort the data. But there is an issue withORDER BY bid DESC, budget DESC, campaign_id ASC. Note that there is a mixture ofDESCandASC. MySQL can only scan an index in one direction. This implies that all must beASCor all must beDESC. (See note below) So,INDEX(ad_unit, day, bid, budget, campaign_id)is not as useful as you would like.If the Optimizer could get past step 2, then adding any other columns mentioned anywhere in the
SELECT(namely all of*), then the index would be come "covering". This gives a different variety of performance boost -- by doing all the work in the index, not having to touch the 'data'.Note: Beginning with Version 8.0, MySQL will honor
DESCin index declarations. So, you could sayINDEX(ad_unit, day, bid DESC, budget DESC, campaign_id ASC), and the Optimizer could use it without sorting in item 2, above. (Pre-8.0,DESCwas allowed, but ignored, in index declarations.)Workaround? It would change the order of the output, but you might accept having all the columns
ASC(or allDESC)?Meanwhile,
INDEX(ad_unit_id, day)is about all that is worth having.