为什么MySQL没有使用GROUP BY查询的这个索引?

时间:2013-07-29 08:55:46

标签: mysql indexing

我有这个大表(有百万条记录),我正在尝试检索每种类型的最后一条记录。

表,索引和查询都非常简单,MySQL没有使用索引的事实意味着我必须忽略一些东西。

表格如下:

CREATE TABLE `MyTable001` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `TypeField` int(11) NOT NULL,
  `Value` bigint(20) NOT NULL,
  `Timestamp` bigint(20) NOT NULL,
  `AnotherField1` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_MyTable001_TypeField` (`TypeField`),
  KEY `idx_MyTable001_Timestamp` (`Timestamp`)
) ENGINE=MyISAM

显示索引给出了这个:

+------------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table      | Non_unique | Key_name                 | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| MyTable001 |          0 | PRIMARY                  |            1 | id          | A         |      626141 |     NULL | NULL   |      | BTREE      |         |               |
| MyTable001 |          1 | idx_MyTable001_TypeField |            1 | TypeField   | A         |         458 |     NULL | NULL   |      | BTREE      |         |               |
| MyTable001 |          1 | idx_MyTable001_Timestamp |            1 | Timestamp   | A         |      156535 |     NULL | NULL   |      | BTREE      |         |               |
+------------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

但是当我为以下查询执行EXPLAIN时:

SELECT   *
FROM    MyTable001
GROUP BY TypeField
ORDER BY id DESC

结果如下:

+----+-------------+------------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows   | Extra                           |
+----+-------------+------------+------+---------------+------+---------+------+--------+---------------------------------+
|  1 | SIMPLE      | MyTable001 | ALL  | NULL          | NULL | NULL    | NULL | 626141 | Using temporary; Using filesort |
+----+-------------+------------+------+---------------+------+---------+------+--------+---------------------------------+

MySQL为什么不使用idx_MyTable001_TypeField

提前致谢。

1 个答案:

答案 0 :(得分:4)

问题是仍然正在检查不在分组中的字段的内容。因此,必须读取所有行,并且最好进行全表扫描。通过以下示例可以清楚地看到这一点:

SELECT TypeField, COUNT(*) FROM MyTable001 GROUP BY TypeField使用索引。

SELECT TypeField, COUNT(id) FROM MyTable001 GROUP BY TypeField没有。

原始查询不正确。正确的查询是:

SELECT l.*
FROM  MyTable001 l
JOIN (
    SELECT MAX(id) m_id
    FROM MyTable001 l
    GROUP BY l.TypeField) l_id ON l_id.m_id = l.id;

在包含630k记录的表中需要260毫秒。在我的测试中,Joachim Isaksson和fancyPants的选择花了几分钟。