为什么索引不能处理非唯一的datetime列?

问题描述 投票:0回答:1

表结构:

CREATE TABLE `stat_old` (
  `dt` datetime NOT NULL,
  `offer_id` int(11) DEFAULT NULL,
  `aff_id` int(11) DEFAULT NULL,
  UNIQUE KEY `dt` (`dt`,`offer_id`,`aff_id`),
  KEY `dt_2` (`dt`),
  KEY `offer_id` (`offer_id`),
  KEY `aff_id` (`aff_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

dt字段存储的日期时间值转换为小时,如'2019-01-01 01:00:00','2019-01-01 02:00:00',并且其非唯一。

查询:

explain select *
FROM stat_old
WHERE
  dt between '2019-02-11 16:00:00' and '2019-02-18 15:59:59'
order by dt;

结果:

+----+-------------+----------+------+---------------+------+---------+------+----------+-----------------------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows     | Extra                       |
+----+-------------+----------+------+---------------+------+---------+------+----------+-----------------------------+
|  1 | SIMPLE      | stat_old | ALL  | dt,dt_2       | NULL | NULL    | NULL | 18914072 | Using where; Using filesort |
+----+-------------+----------+------+---------------+------+---------+------+----------+-----------------------------+

如您所见,它几乎扫描了包含20,044,835行的整个表。实际上结果数据只有2,108,707行。为什么dt的索引不使用?我怎样才能解决这个问题 ?

mysql query-optimization sql-execution-plan
1个回答
2
投票

dt作为主键的第一部分将有助于在dt顺序中检索更大的日期范围:

alter table stat_old
drop key dt,
drop key dt_2,
add primary key (`dt`,`offer_id`,`aff_id`)
© www.soinside.com 2019 - 2024. All rights reserved.