MySQL在索引的TIMESTAMP列上使用filesort

时间:2012-10-25 07:20:23

标签: mysql timestamp indexing

我有一个拒绝使用索引的表,它总是使用filesort。

表格是:

CREATE TABLE `article` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Category_ID` int(11) DEFAULT NULL,
  `Subcategory` int(11) DEFAULT NULL,
  `CTimestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `Publish` tinyint(4) DEFAULT NULL,
  `Administrator_ID` int(11) DEFAULT NULL,
  `Position` tinyint(4) DEFAULT '0',
  PRIMARY KEY (`ID`),
  KEY `Subcategory` (`Subcategory`,`Position`,`CTimestamp`,`Publish`),
  KEY `Category_ID` (`Category_ID`,`CTimestamp`,`Publish`),
  KEY `Position` (`Position`,`Category_ID`,`Publish`),
  KEY `CTimestamp` (`CTimestamp`),
  CONSTRAINT `article_ibfk_1` FOREIGN KEY (`Category_ID`) REFERENCES `category` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=94290 DEFAULT CHARSET=utf8

查询是:

SELECT * FROM article ORDER BY `CTimestamp`;

解释是:

+----+-------------+---------+------+---------------+------+---------+------+-------+----------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows  | Extra          |
+----+-------------+---------+------+---------------+------+---------+------+-------+----------------+
|  1 | SIMPLE      | article | ALL  | NULL          | NULL | NULL    | NULL | 63568 | Using filesort |
+----+-------------+---------+------+---------------+------+---------+------+-------+----------------+

当我删除“ORDER BY”时,所有都正常工作。所有其他索引(子类别,位置等)在其他查询中正常工作。不幸的是,即使使用我的简单选择查询,也会拒绝使用时间戳。我确定我在这里缺少一些重要的东西。

如何让MySQL使用时间戳索引?

谢谢。

2 个答案:

答案 0 :(得分:5)

在这种情况下,MySQL没有使用你的索引进行排序,这是一件好事。 为什么?您的表只包含64k行,平均行宽约为26个字节(如果我向右添加列大小),因此磁盘上的总表大小应该在2MB左右。 从磁盘读取2MB数据到内存非常便宜(可能只需1-2次磁盘操作或搜索),然后只需在内存中执行filesort(可能是quicksort的变体)。

如果MySQL按照您的意愿按索引顺序进行检索,则必须执行64000个磁盘搜索操作,一个接一个记录!这本来是非常非常慢的。

当您可以使用它们快速跳转到大文件中的已知位置并读取少量数据时,索引就可以很好,就像在WHERE子句中一样。但是,在这种情况下,这不是一个好主意 - 而MySQL并不是愚蠢的!

如果你的表非常大(超过RAM大小),那么MySQL肯定会开始使用你的索引 - 这也是好事。

答案 1 :(得分:0)

好吧,你总是可以提示索引。将您的查询更改为

SELECT * FROM article use index (CTimestamp);

这迫使MySQL使用索引进行查询。解答:

1, 'SIMPLE', 'article', 'ALL', '', '', '', '', 1, 100.00, ''

没有要查看的文件,并且由于使用的索引是CTimestamp,因此应该相应地对结果进行排序。

或者,您可以保留order by子句,但强制使用索引:

SELECT * FROM article force index (CTimestamp) order by CTimestamp;

但问题仍然很奇怪。您是否考虑将其发布到官方MySQL帮助论坛?

编辑:您似乎是in good company 编辑:强制索引seems to work out well