如何避免这个mysql查询的文件排序
Posted
技术标签:
【中文标题】如何避免这个mysql查询的文件排序【英文标题】:How to avoid filesort for this mysql query 【发布时间】: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<'10016' and id<'9869788'
?考虑排序数字和字符串是不同的。例如。 1
@Asaph:在可能的情况下,隐式转换由列数据类型决定。如果did
是数字,您会不会期望与字符串进行比较时出错? ;)
@OMG Ponies:我在 mysql 中进行了一些测试,并证实了您所说的。固执地,我认为选择将字符串转换为整数(可能有损)而不是将整数转换为字符串(非有损)在逻辑纯粹主义者的意义上是完全错误的。但从实际的角度来看,将字符串转换为整数几乎总是用户想要的。所以我认为这个选择是合理的。 @Vern:感谢您试用。无论如何,您都应该删除引号,即使性能没有提高。
【参考方案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 是唯一的,您还可以为其创建主键。
您的查询正在使用文件排序,因为优化器可能正在使用您在查询中创建的索引的第一列。
【讨论】:
以上是关于如何避免这个mysql查询的文件排序的主要内容,如果未能解决你的问题,请参考以下文章