我有以下查询,它显示了每天发出请求的不同 IP 地址。
SELECT COUNT(DISTINCT ip_address) as ip_address, DATE(exec_datetime) as day
FROM requests
GROUP BY MONTH(exec_datetime), DAY(exec_datetime);
的输出EXPLAIN
如下
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE requests ALL NULL NULL NULL NULL 472043 Using filesort
我对覆盖索引没有清楚的了解,因为当我创建一个时,查询需要很长时间才能完成
ALTER TABLE requests ADD INDEX unique_ip_per_time(ip_address, exec_datetime);
这是输出EXPLAIN
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE requests index NULL unique_ip_per_time 268 NULL 472043 Using index; Using filesort
我如何通过创建索引或重写来优化此查询?
编辑
两个语句的执行时间约为 15 秒(有和没有覆盖索引)。此表上唯一的其他键是UNIQUE
代理和INDEX
onip_address
show indexes from requests
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
requests 0 PRIMARY 1 request_id A 386577 NULL NULL BTREE
requests 1 ip_address 1 ip_address A 193288 NULL NULL YES BTREE
requests 1 unique_ip_per_time 1 ip_address A 163 NULL NULL YES BTREE
requests 1 unique_ip_per_time 2 exec_datetime A 163 NULL NULL YES BTREE
编辑 2
我按照 eisberg 的说明进行操作,但是此查询大约需要 1.1 秒...
EXPLAIN SELECT
A.request_day,
(
SELECT COUNT(DISTINCT B.ip_address)
FROM requests B
WHERE B.exec_date = A.request_day
) as num_ip_addr
FROM request_days A
ORDER BY A.request_day ASC;
这比这个大约需要 0.9 秒的查询稍慢
SELECT COUNT(DISTINCT ip_address) as ip_address, exec_date
FROM requests
GROUP BY exec_date;
我认为我不需要创建带有日期的附加表。是否有任何优化可以应用于部分语句DISTINCT ip_address
(这似乎是瓶颈)?