My InnoDB table has about 1 billion log entries. I am trying to do a simple select on the table resulting in about 30 million rows. The query consists of a range condition on an int field holding a timestamp.
Query:
SELECT * FROM logs WHERE created_at >= 1446422400 AND created_at <= 1447027199
This query has a poor performance, running about 6-7 hours and only getting about 1.000 rows/sec. created_at has an index on it and the query is using the index. When I do a simple SELECT * FROM logs WHERE id >= xx AND id <= yy
, setting xx and yy so that the result set is nearly the same (30 million rows), performance is great, running max. 10 minutes.
This really bugs me out. Why does the range on PK work so great and on the index so bad? How can I optimize the index? I've recreated the table few days ago, so indices should be fine.
Some more info:
Table scheme:
| 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 |
Explain:
| 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 |
Goal:
My goal is to retrieve data from the table in weekly-chunks. The range above specifies a week range. Later I want to query the whole table in batches, getting always the data of a specific week.