【问题标题】:How to avoid filesort for this mysql query如何避免这个mysql查询的文件排序
【发布时间】:2011-07-12 03:08:17
【问题描述】:

我需要一些帮助来避免对该查询进行文件排序。

  SELECT id 
    FROM articles USE INDEX(group)
   WHERE type = '4' 
     AND category = '161' 
     AND did < '10016' 
     AND id < '9869788' 
ORDER BY id DESC 
   LIMIT 10

INDEX(group) 是 (type, category, did, id) 的覆盖索引

由于ORDER BY id DESC,执行文件排序。有没有办法避免对此类查询进行文件排序?

【问题讨论】:

  • 所有这些列的数据类型是数字(例如 int)吗?如果是这样,请从查询中的所有数字中删除引号。这将大大加快速度。
  • @Asaph:隐式转换可能没什么大不了的;我会删除单引号,因为它们给人的印象是错误的(假设列数据类型是数字)
  • @OMG Ponies:你确定吗?即使对于这部分查询:did&lt;'10016' and id&lt;'9869788'?考虑排序数字和字符串是不同的。例如。 1
  • @Asaph:在可能的情况下,隐式转换由列数据类型决定。如果did 是数字,您会不会期望与字符串进行比较时出错? ;)
  • @OMG Ponies:我在 MySQL 中进行了一些测试,并证实了您所说的。固执地,我认为选择将字符串转换为整数(可能有损)而不是将整数转换为字符串(非有损)在逻辑纯粹主义者的意义上是完全错误的。但从实际的角度来看,将字符串转换为整数几乎总是用户想要的。所以我认为这个选择是合理的。 @Vern:感谢您试用。无论如何,您都应该删除引号,即使性能没有提高。

标签: mysql sql sql-order-by filesort


【解决方案1】:

更改索引列顺序。该索引对排序没有用处,因为它是第 4 列,还不能按原样使用。

当然,这会影响索引对这个 WHERE 的有用性,因为在相等列之前需要一个不等列

MySQL docs 中,您破坏了“您在键的非连续部分上使用 ORDER BY”和“用于获取行的键与 ORDER BY 中使用的键不同”

编辑:根据我上面的链接,您不能拥有同时满足 WHERE 和 ORDER BY 的索引。由于我在上面发布的两个条件,它们是互斥的

另一个建议:

  • id 上的单列索引
  • 也回到原来的索引
  • 移除索引提示
  • 希望优化器解决两个索引都可以使用(“索引交集”)

【讨论】:

  • 那么你建议什么顺序?也许(id、did、type、category)?
  • @Vern:最常用的列在左侧,第二常用的列在第二位,依此类推。
  • @OMG Ponies:具体到这个查询,什么顺序会避免文件排序?
  • Id 在前,因此它与排序匹配。
  • @Vern:天哪。再说一遍:id 不应该是第一个。请仔细阅读该链接。尤其是第二个例子,关于 key_parts
【解决方案2】:

在 id 上创建索引并键入它应该适合您。 如果 Id 是唯一的,您还可以为其创建主键。

您的查询正在使用文件排序,因为优化器可能正在使用您在查询中创建的索引的第一列。

【讨论】:

    猜你喜欢
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    • 2011-07-02
    • 2020-11-21
    • 2021-11-11
    • 2013-07-07
    • 1970-01-01
    相关资源
    最近更新 更多