MySQL在索引的TIMESTAMP列上使用filesort

Jim*_*mbo 3 mysql indexing timestamp

我有一个拒绝使用索引的表,它总是使用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使用时间戳索引?

谢谢.

mvp*_*mvp 5

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

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

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

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