MySQL计数(不同)非常慢-使用子查询更好?
我有一个平面表,大约有10mio行,每行有15列。 索引设置为第1列、第2列、第3列和我的时间MySQL计数(不同)非常慢-使用子查询更好?,mysql,select,count,subquery,distinct,Mysql,Select,Count,Subquery,Distinct,我有一个平面表,大约有10mio行,每行有15列。 索引设置为第1列、第2列、第3列和我的时间 SELECT Date(my_time) my_time, count(DISTINCT column_1) c_c1, count(DISTINCT column_2) c_c2 FROM `table_name` WHERE `column_3` in (10,11,100,50,213,756)
SELECT Date(my_time) my_time,
count(DISTINCT column_1) c_c1,
count(DISTINCT column_2) c_c2
FROM `table_name`
WHERE `column_3` in (10,11,100,50,213,756)
AND Date(my_time) > '2016-09-01'
AND Date(my_time) < '2016-09-30'
GROUP BY Date(my_time)
ORDER BY Date(my_time) ASC
选择日期(我的时间)我的时间,
计数(不同列_1)c_c1,
计数(不同列_2)c_c2
从'table_name'开始
式中,`column_3`in(10,11100,50213756)
日期(我的时间)>“2016-09-01”
日期(我的时间)<'2016-09-30'
按日期分组(我的时间)
按日期(我的时间)订购ASC
结果大约需要20-30秒
有人知道如何改进这个查询吗,也许是子查询?
在子查询的情况下,您能否向我展示一个示例查询,如何提高性能
谢谢 您可能可以使用适当的索引来加快速度:
create index idx_speedy on table_name(column_3, my_time);
甚至最好是一个覆盖指数:
create index idx_speedy on table_name(column_3, my_time, column_1, column_2);
为了更好地利用索引,请尽量避免在where子句中的列上使用函数,即避免Date(my_time)
here
SELECT Date(my_time) my_time,
COUNT(DISTINCT column_1) AS c_c1,
COUNT(DISTINCT column_2) AS c_c2
FROM table_name
WHERE column_3 in (10, 11, 100, 50, 213, 756)
AND my_time >= '2016-09-02'
AND my_time < '2016-09-30'
GROUP BY Date(my_time)
ORDER BY Date(my_time) ASC;
选择日期(我的时间)我的时间,
将(不同列_1)计数为c_c1,
将(不同列_2)计数为c_c2
从表\u名称
其中列_3 in(10,11,100,50,213,756)
我的时间>='2016-09-02'
我的时间<'2016-09-30'
按日期分组(我的时间)
按日期(我的时间)订购ASC;
如果MySQL支持函数索引,我们可以坚持使用日期(my_time)并为您的查询创建此索引:
create index idx_speedy on table_name(column_3, Date(my_time), column_1, column_2);
由于MySQL不支持此功能,您可以决定创建一个生成的列:
alter table table_name add my_date date generated always as ( Date(my_time) );
创建索引
create index idx_speedy on table_name(column_3, my_date, column_1, column_2);
并相应地重新编写查询:
SELECT my_date,
COUNT(DISTINCT column_1) AS c_c1,
COUNT(DISTINCT column_2) AS c_c2
FROM table_name
WHERE column_3 in (10, 11, 100, 50, 213, 756)
AND my_date BETWEEN '2016-09-02' AND '2016-09-29'
GROUP BY my_date
ORDER BY my_date ASC;
如果我没有弄错的话,这可以从MySQL 5.7.6开始使用。做一个测试,并在你的答案中发布。尝试在“2016-09-01 00:00:00”和“2016-09-30 23:59:59”之间更改为我的时间id:1选择类型:简单表:表名称类型:所有可能的关键字:我的时间,列关键字:空关键字:空关键字:空参考:空行:。。。。额外:在何处使用;使用filesort这将大大加快查询速度。但是我认为你也应该有一个单独的
索引my_time
来加速订单,因为条款没有任何改进。现在解释给我看:id:1选择类型:简单表格:表格名称类型:索引可能的关键字:我的时间,列3,速度关键字:速度关键字:173参考:空行:。。。。额外:使用where,使用index,使用filesort太糟糕了,我认为这和给定的表一样快@朱修斯:不,那没用;排序不是在my\u time
上完成的,而是在Date(my\u time)
上完成的,而且无论如何my\u time
已经在我的索引中。