带索引的范围查询痛苦地慢

时间:2015-11-22 16:41:56

标签: mysql performance innodb query-performance

我的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 |

目标:

我的目标是以每周块的形式从表中检索数据。上述范围指定一周范围。后来我想分批查询整个表格,总是获得特定周的数据。

1 个答案:

答案 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