我的InnoDB表有大约10亿个日志条目。我尝试在表上执行一个简单的select操作,结果大约有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万行)时,运行max时,性能非常好。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 |
目标:
我的目标是以每周为单位从表中检索数据。上面的范围指定了周范围。稍后,我想分批查询整个表,始终获取特定周的数据。
发布于 2015-11-23 01:05:45
id
查询速度如此之快的原因很可能是因为mysql为id
创建了一个聚集索引,因为它是主键,而created_at
索引不是聚集索引,因为created_at
不是主键。
我不确定为什么会有这么大的差异,因为created_at
的日期很可能和id
一样是连续的,但显然是这样的。
所以,试试这个:
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
https://stackoverflow.com/questions/33857310
复制相似问题