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

表,索引和查询都非常简单,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

提前致谢。

最佳答案

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

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和fancyPant的替代品花费了几分钟。

10-04 13:38