我有一个类似
的表结构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
为什么无法找到我定义为主键的索引?
答案 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的错误......