0

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

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

提前致谢。

4

1 回答 1

5

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

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 的替代品在我的测试中花了几分钟时间。

于 2013-07-29T09:13:15.067 回答