MySQL:为啥简单查询不使用索引,执行文件排序

Posted

技术标签:

【中文标题】MySQL:为啥简单查询不使用索引,执行文件排序【英文标题】:MySQL: Why is simple query not using index, performing filesortMySQL:为什么简单查询不使用索引,执行文件排序 【发布时间】:2014-12-05 19:39:26 【问题描述】:

我有一个这样定义的表:

`id` int(10) NOT NULL AUTO_INCREMENT,
`slug` varchar(150) NOT NULL,
`title` varchar(150) NOT NULL,
`description` text NOT NULL,
`ordinal` int(10) NOT NULL DEFAULT '0'

我们称之为t1

t1 中,我在 ordinal 上有一个索引。

这个表只包含几行,它是一个定义表,所以我通常这样做,以按我想要的顺序获取定义

SELECT * FROM t1 WHERE 1 ORDER BY ordinal;

如果我对该语句执行 EXPLAIN,我会得到以下信息:

id? select_type?    table?  partitions? type?   possible_keys?  key?    key_len?    ref?    rows?   Extra?
1   SIMPLE  t1  NULL    ALL NULL    NULL    NULL    NULL    5   Using where; Using filesort

上面的行是否对齐并不重要。重要的是它使用了文件排序,我不知道为什么。

由于该表中只有 5-10 行,因此可能感觉它并不重要,但文件排序让我的 open_tables 变得有点糟糕,因为 mysql(根据强大的互联网)打开了两个表对于它需要执行的每个文件排序查询。

所以,非常感谢这里的任何帮助。谢谢。

【问题讨论】:

您有 5 行。我想在这么小的数据集上使用索引不会被打扰 计划注释“使用 where”,这有点危险,因为每一行都满足您的 WHERE 子句。在分析如何以及是否使用索引时,优化器可能会专注于连接和选择谓词。可能您的索引被忽略了,因为它对这些没有帮助。完全删除WHERE 可能会说服它考虑使用索引来协助ORDER BY。或者,由于只有几行并且 MySQL 必须全部读取它们,因此直接对它们进行排序可能会更快。 约翰:你可能是对的。删除“where 1”并没有帮助。奇怪的是,我真的只是希望它不要像为文件排序那样创建一个 tmp 表,因为我有一个“打开表”问题,这似乎部分来自这些具有文件排序的查询。 【参考方案1】:

您的表在“序数”列上没有任何可能被利用的索引。此外,由于您的 WHERE 子句位于固定的“1”值上,该值始终为真,但没有要比较的列,甚至没有查找索引来帮助,它无法选择任何东西......所以您正在经历文件排序。 .. 没有适用于 where 的索引,也没有适用于 order by 子句的索引。

【讨论】:

索引在那里,我只是没有放在上面的文字中。我的主要问题实际上是如何避免文件排序,因为它带有行李。但仍然感谢您写一个答案。 @Adergaard,通过尝试根据预期的查询条件精心规划索引来避免文件排序。此外,学习使用复合 AND 覆盖索引。在处理总计和聚合时,尤其是在 Web 中,不要害怕拥有更高级别的总计/计数列,以防止不断查询底层详细信息。

以上是关于MySQL:为啥简单查询不使用索引,执行文件排序的主要内容,如果未能解决你的问题,请参考以下文章

为啥 MySQL 对此查询执行文件排序?

为啥存在唯一索引时 MySQL Innodb “创建排序索引”?

如何查看MySQL执行计划

MYSQL在简单查询中使用ORDER BY索引列时使用文件排序

为啥在另一个数据库中执行相同查询时不使用索引?

为啥我在这个非常简单的 MySQL 查询上得到文件排序?