为什么MySQL在此查询中执行文件排序?

时间:2017-12-10 19:36:31

标签: mysql indexing filesort

为什么MySQL在此查询中执行文件排序?我只期待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

(ad_unit_id, day, bid, budget, campaign_id)上的索引 - 数据库根据EXPLAIN使用此索引。

在此特定结果集中,bidbudget对于所有行都相同。 (ad_unit_id, campaign_id)是唯一的。

说明:

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

1 个答案:

答案 0 :(得分:3)

让我们剖析查询..

  1. WHERE ad_unit_id=1 AND day='2017-12-10'需要一个以ad_unit_idday开头的索引(按任意顺序排列)。这将提供最佳过滤。

  2. 如果可行的话,可以将ORDER BY添加到INDEX,以避免必须对数据进行排序。但是ORDER BY bid DESC, budget DESC, campaign_id ASC存在问题。请注意,DESCASC混合在一起。 MySQL只能在一个方向上扫描索引。这意味着所有内容必须为ASC或全部必须为DESC。 (见下面的注释)因此,INDEX(ad_unit, day, bid, budget, campaign_id)没有您想要的那么有用。

  3. 如果优化工具可以通过第2步,然后在SELECT(即所有*)中添加 的任何其他列,那么索引会来“覆盖”。这提供了不同的性能提升 - 通过在索引中完成所有工作,而不必触及'数据'。

  4. 注意:从版本8.0开始,MySQL将在索引声明中表示DESC。因此,您可以说INDEX(ad_unit, day, bid DESC, budget DESC, campaign_id ASC),优化工具可以在上面的第2项中使用而无需排序。 (8.0之前,DESC被允许,但在索引声明中被忽略。)

    解决方法?它会改变输出的顺序,但您可以接受所有列ASC(或所有DESC)?

    与此同时,INDEX(ad_unit_id, day)就是值得拥有的一切。