我有这个大表(约有数百万条记录),并且我正在尝试检索每种类型的最后一条记录。
表,索引和查询都非常简单,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的替代品花费了几分钟。