我有一张表clicks
:
CREATE TABLE `clicks` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`link_id` int(11) NOT NULL,
`date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
PRIMARY KEY (`id`),
KEY `link_id` (`link_id`),
KEY `date_added` (`date_added`)
) ENGINE=InnoDB AUTO_INCREMENT=90899051 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
使用以下索引:
+--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| clicks | 0 | PRIMARY | 1 | id | A | 79808649 | NULL | NULL | | BTREE | | |
| clicks | 1 | link_id | 1 | link_id | A | 276154 | NULL | NULL | | BTREE | | |
| clicks | 1 | date_added | 1 | date_added | A | 79808649 | NULL | NULL | | BTREE | | |
+--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
我试图在这张桌子上运行一些分析性查询,而且我发现它需要花费很长时间才能运行。以下面的查询为例:
SELECT
DISTINCT(link_id) AS link_id
FROM
clicks
WHERE
date_added >= '2016-11-01 00:00:00'
AND date_added <= '2016-12-05 10:16:00'
这个查询花了差不多一分钟才完成。我通过在查询上运行EXPLAIN
找到索引未被使用。
+----+-------------+--------+-------+---------------+---------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+------+----------+-------------+
| 1 | SIMPLE | clicks | index | date_added | link_id | 4 | NULL | 79786609 | Using where |
+----+-------------+--------+-------+---------------+---------+---------+------+----------+-------------+
我希望通过使用date_added
列上的索引来过滤结果集,然后从结果中提取不同的link_id
,就可以运行查询。
有谁知道为什么索引没有被使用,或者我有什么办法可以强迫它被使用?
注意:此问题是更大问题的一部分,与我上周发布的未解决问题密切相关 - MySQL query with JOIN not using INDEX
修改
在不使用任何索引提示的情况下解释我的查询:
EXPLAIN SELECT DISTINCT(link_id) FROM clicks WHERE date_added >= '2016-11-01 00:00:00' AND date_added <= '2016-12-05 23:59:59';
+----+-------------+---------------------------+-------+---------------+---------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------------+-------+---------------+---------+---------+------+----------+-------------+
| 1 | SIMPLE | clicks | index | date_added | link_id | 4 | NULL | 79816660 | Using where |
+----+-------------+---------------------------+-------+---------------+---------+---------+------+----------+-------------+
解释我的查询WITH索引提示:
EXPLAIN SELECT DISTINCT(link_id) FROM clicks USE INDEX(date_added) IGNORE INDEX(link_id) WHERE date_added >= '2016-11-01 00:00:00' AND date_added <= '2016-12-05 23:59:59';
+----+-------------+---------------------------+------+---------------+------+---------+------+----------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------------+------+---------------+------+---------+------+----------+------------------------------+
| 1 | SIMPLE | clicks | ALL | date_added | NULL | NULL | NULL | 79816882 | Using where; Using temporary |
+----+-------------+---------------------------+------+---------------+------+---------+------+----------+------------------------------+
修改2
在我的查询中使用FORCE INDEX(date_added)
(查询更快完成,12.05秒):
EXPLAIN SELECT DISTINCT(link_id) FROM clicks FORCE INDEX(date_added) WHERE date_added >= '2016-11-01 00:00:00' AND date_added <= '2016-12-05 23:59:59';
+----+-------------+---------------------------+-------+---------------+------------+---------+------+----------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------------+-------+---------------+------------+---------+------+----------+------------------------------+
| 1 | SIMPLE | clicks | range | date_added | date_added | 4 | NULL | 17277508 | Using where; Using temporary |
+----+-------------+---------------------------+-------+---------------+------------+---------+------+----------+------------------------------+