我的InnoDB表有大约10亿个日志条目。我试图在桌面上做一个简单的选择,产生大约3000万行。该查询由包含时间戳的int字段的范围条件组成。
查询:
SELECT * FROM logs WHERE created_at >= 1446422400 AND created_at <= 1447027199
此查询的性能较差,运行时间约为6-7小时,只能达到约1.000行/秒。 created_at上有一个索引,查询正在使用索引。当我做一个简单的SELECT * FROM logs WHERE id >= xx AND id <= yy
时,设置xx和yy以便结果集几乎相同(3000万行),性能很好,运行最大值。 10分钟。
这真让我烦恼。为什么PK的范围如此之大以及索引如此糟糕?我该如何优化索引?我几天前重新创建了这个表,因此索引应该没问题。
更多信息:
表格方案:
| logs | CREATE TABLE `logs` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`categoryid` varchar(15) NOT NULL,
`type` varchar(15) NOT NULL,
`text` varchar(500) NOT NULL,
`created_at` int(7) NOT NULL,
`status` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
KEY `status_categoryid_type` (`status`,`categoryid`,`type`),
KEY `created_at` (`created_at`),
) ENGINE=InnoDB AUTO_INCREMENT=1335078012 DEFAULT CHARSET=latin1 |
说明:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+---------+-------+----------------------------+---------+------+----------+-----------------------+
| 1 | SIMPLE | logs | range | created_at | created_at | 4 | NULL | 31707348 | Using index condition |
目标:
我的目标是以每周块的形式从表中检索数据。上述范围指定一周范围。后来我想分批查询整个表格,总是获得特定周的数据。
答案 0 :(得分:0)
id
的查询工作速度如此之快的原因很可能是因为mysql为id
创建了聚簇索引,因为它是主键,而created_at
索引是没有群集,因为created_at
不是主键。
我不确定为什么差异如此之大,因为created_at
日期很可能与id
s一样顺序,但显然它是。
所以,试试这个:
SELECT id FROM logs WHERE created_at >= 1446422400 LIMIT 1
(将结果分配给id1)
SELECT id FROM logs WHERE created_at <= 1447027199 ORDER BY id DESC LIMIT 1
(将结果分配给id2)
SELECT * FROM logs WHERE id >= id1 AND id <= id2