Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL计数(不同)非常慢-使用子查询更好?_Mysql_Select_Count_Subquery_Distinct - Fatal编程技术网

MySQL计数(不同)非常慢-使用子查询更好?

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)

我有一个平面表,大约有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) 
     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
已经在我的索引中。