3

我有一个具有以下架构的表

Id , INT, 主键

查询 ID, INT

创建时间,日期时间

我创建了复合索引(QueryId,CreatedTime)

为什么当我运行 explain select * from test where queryid in (1,6) order by createdtime desc 时

我仍然得到以下具有文件排序的内容?知道如何删除文件排序吗? “使用位置;使用文件排序”

解释结果

4

1 回答 1

1

您实际上还没有构建可用于该查询的索引。

索引只能用于从最左边的列向右进行查找和排序。一旦遇到无用的东西,索引的其余部分就会被忽略。

您没有发布您的输出,EXPLAIN但我怀疑如果正在检查索引并且 QueryId 是 an INT,您会发现Key_len= 4 意味着只有最左边的 4 个字节(QueryId)对优化器有用。

(QueryId,CreatedTime) 上的索引,用于按 QueryId 提取记录,并在且仅当您为 QueryId 选择单个值时按 CreatedTime 对它们进行排序。当您这样做时,索引将返回与该 QueryId 匹配的行,这些行已经按 CreatedTime 排序,并且优化器会意识到这一点。

相反,如果您查找 QueryId 的多个值,则索引返回的行将按 QueryId 排序,然后按每组 QueryId 中的 CreatedTime 排序返回...因此需要进一步的文件排序,因为 CreatedTime 值本质上是无用的排序命令。如果您使用ORDER BYQueryId、CreatedTime,那么文件排序当然应该消失,但这可能不是您想要的。

(CreatedTime,QueryId) 上的索引也无济于事,因为 QueryId 不在左侧,除非行数非常少,否则服务器可以提取由 CreatedTime 预先排序的行,但它会必须扫描所有行以查找 QueryId 的匹配值。

简而言之,你不能为这样的查询完全Using filesort索引,也不是总是可以避免的。

于 2013-10-17T05:02:40.220 回答