使用“FileSort”的Mysql Order by子句

时间:2012-08-12 08:51:58

标签: mysql indexing database-performance explain

我有一个类似

的表结构
comment_id primary key
comment_content 
comment_author
comment_author_url

当我解除像

这样的查询时
explain SELECT * FROM comments  ORDER BY comment_id

将结果输出为

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  comments    ALL     NULL    NULL    NULL    NULL    22563   Using filesort

为什么无法找到我定义为主键的索引?

2 个答案:

答案 0 :(得分:11)

这不是因为它无法使用索引。这是因为优化器认为不使用索引并执行文件分析 1 更快。您应该在MyiSAM和InnoDB表中看到不同的行为。

InnoDB将PRIMARY密钥创建为群集密钥(如果未定义主要密钥,则创建第一个UNIQUE),这可用于ORDER BY pk或{{1}的查询因为所需的所有值都在此群集密钥和连续位置(群集密钥 表)。

MyISAM表只有B树索引,所以如果查询使用了这个索引,它必须读取整个索引,并且它会在所需的顺序中有WHERE pk BETWEEN low AND high个值(这真的很好)但它会然后必须阅读表格(不太好)以获得所有其他想要的列。因此,优化器认为,既然它将读取表,为什么不扫描它并执行filesort?您可以通过尝试来测试:

comment_id

它将使用索引并且不执行任何文件排序,因为查询只需要存储在索引中的值。


如果您想在MyiSAM中使用类似的(对InnoDB)行为,您可以尝试在SELECT comment_id FROM comments ORDER BY comment_id ; 上创建索引,然后尝试查询。所有需要的值都可以在索引上找到并且顺序正确,因此不会执行任何文件输出。

附加索引当然需要与磁盘一样多的磁盘空间。


1 :filesort并不总是坏的,并不意味着文件保存在磁盘上。如果数据的大小很小,则在内存中执行。

答案 1 :(得分:7)

无论何时无法从索引执行排序,它都是一个文件排序。

这里奇怪的是你应该在该字段上有索引,因为它是主键(并且主键列是隐式索引的),在测试数据库上测试我只是注意到MySQL在你执行任何时候都使用FileSort SELECT *,这是一种无意义的行为(我知道)但是如果你以这种方式重写你的查询:

SELECT comment_id, comment_content, comment_author, comment_author_url 
FROM comments  
ORDER BY comment_id

它将正确使用索引。也许可能是mysql的错误......