【问题标题】:MySQL: Why is this SQL-query not using index?MySQL:为什么这个 SQL 查询不使用索引?
【发布时间】:2014-12-17 18:32:04
【问题描述】:

我有一个非常简单的 SELECT,它使用文件排序并且不使用索引。

考虑以下查询:

SELECT * FROM forum_topic
WHERE topic_status = 0
ORDER BY modified_date LIMIT 0, 30

在下表中(去掉几列以使其更简短

CREATE TABLE `forum_topic` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`slug` varchar(255) NOT NULL,
`forum_id` int(10) NOT NULL DEFAULT '1',
`title` varchar(100) NOT NULL,
`topic_status` tinyint(1) NOT NULL DEFAULT '0',
`post_count` bigint(20) NOT NULL DEFAULT '0',
`modified_date` datetime NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `slug` (`slug`),
  FULLTEXT KEY `title` (`title`),
  KEY `modified` (`modified_date`, `topic_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

EXPLAIN 给出以下输出

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

请注意解释如何说可能的键为 NULL,以及它在扫描所有行后如何使用文件排序。

请指教。谢谢。

【问题讨论】:

  • 您的 modified 索引可能会将字段向后;有多少行?

标签: mysql indexing explain


【解决方案1】:

此查询需要topic_status 出现在索引的最重要位置,因为它正在搜索一个常量。

你有

   KEY `modified` (`modified_date`, `topic_status`)

你可能想要

   KEY `mod2` (`topic_status`, `modified_date` )

相反。这可能同时满足过滤器和查询的ORDER BY ... LIMIT 部分。

专业提示:避免使用SELECT *,而是枚举您实际需要的列。

专业提示:文件排序不一定意味着您认为的意思。它在 MySQL 需要为排序等构建中间结果集的任何时候使用。

【讨论】:

  • 好的,谢谢。它现在仍然使用“索引条件”,但仍然必须使用所有行。此外,当在此添加一些 LEFT JOIN 时,为了从其他表中获取用户名和论坛名称之类的内容,它再次求助于“使用索引条件;使用临时;使用文件排序”——这不好,对吗?
猜你喜欢
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 1970-01-01
  • 2013-10-29
  • 2011-10-05
  • 1970-01-01
  • 2011-08-24
相关资源
最近更新 更多