我有这个大表(有百万条记录),我正在尝试检索每种类型的最后一条记录。
表,索引和查询都非常简单,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
?
提前致谢。
答案 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的选择花了几分钟。