一个查询花了50分钟,大神们有什么优化的方法吗?

时间:2021-08-02 08:52:39
查询22日当天的用户量
sql语句如下: select count(distinct phone) from user where DATE_FORMAT(DATE,'%Y-%m-%d') = '2017-11-22';
执行结果:+-----------------------------+
                 | count(distinct phone) |
                 +-----------------------------+
                 |                748032          |
                 +-----------------------------+
                1 row in set (50 min 21.12 sec)
有啥子优化的方法吗?

8 个解决方案

#1



#建立一个非聚集索引在user表的date列上
create UNIQUE index CL_dt_user on `USER`(date)

select count(distinct phone) from user where date between '2017-11-22 00:00:00' and '2017-11-22 23:59:59'

#2


1. 在date字段上添加索引,不需要唯一索引,唯一索引的话,如果系统并发量高的话,其实是会添加失败的。

2. 使用between, 或者 <= 和 >=  这种方法,更好的是计算时间戳,时间戳是会走索引的,

3. 如果不改变索引的情况下,可以考虑让系统走唯一能标识用户的列,例如:  如果用户表主键有序且一个id代表一个用户,则可以统计时间段内的主键,差值,就可以统计注册量了,

4. 另外这条语句没看执行计划吧,先看看执行计划。50分钟,要么是数据量很大,要么每建立任何索引吧!

最近个人公众号《andyqian》上更新了不少,关于数据库优化,索引方面的文章,有兴趣可以来看看!应该对你有帮助!

#3


select count(distinct phone) from user where date(DATE) = '2017-11-22'
  

#4


从50分钟这个时间看,你这查询已经和数据量没关系了,date字段上有索引没有?没有加上,如果没权限更改表结构,那通过代码或者其他方式使查询条件落在有索引的列上,至少要让有索引的列出现在查询条件中,海量数据查询不走索引这是...我也不知说什么好了。另外不要使用任何mysql函数,会使索引无效而进行全表扫描

#5


我来说两句吧

首先,第一句:
select嵌套,一先把所有2017-11-22的distinct的phone找出来,然后再count,或者先count,再distinct

当然,重点第二句:
换SSD!换SSD!换SSD!

尼玛我曾今抓破脑子想优化,有毛线用,换了个SSD,那酸爽.....哎,真是钱花到哪好到哪...

#6


where DATE_FORMAT(DATE,'%Y-%m-%d') = '2017-11-22';  这样肯定全表扫描。字段不要用函数,重要的说3遍

#7


我建议你分两步:第一步建date 索引;
第二步:修改一下my.ini配置文件,innodb_buffer_pool_size 增大这个数值,同时logfile也要增大,这样你的时间会缩短。

我用相同的数据测试了一下,我用了443.31秒,因为我的硬件是笔记本2G内存,如果是服务器时间可以更短。

#8


感谢各位大神们的回复,已结贴给分

#1



#建立一个非聚集索引在user表的date列上
create UNIQUE index CL_dt_user on `USER`(date)

select count(distinct phone) from user where date between '2017-11-22 00:00:00' and '2017-11-22 23:59:59'

#2


1. 在date字段上添加索引,不需要唯一索引,唯一索引的话,如果系统并发量高的话,其实是会添加失败的。

2. 使用between, 或者 <= 和 >=  这种方法,更好的是计算时间戳,时间戳是会走索引的,

3. 如果不改变索引的情况下,可以考虑让系统走唯一能标识用户的列,例如:  如果用户表主键有序且一个id代表一个用户,则可以统计时间段内的主键,差值,就可以统计注册量了,

4. 另外这条语句没看执行计划吧,先看看执行计划。50分钟,要么是数据量很大,要么每建立任何索引吧!

最近个人公众号《andyqian》上更新了不少,关于数据库优化,索引方面的文章,有兴趣可以来看看!应该对你有帮助!

#3


select count(distinct phone) from user where date(DATE) = '2017-11-22'
  

#4


从50分钟这个时间看,你这查询已经和数据量没关系了,date字段上有索引没有?没有加上,如果没权限更改表结构,那通过代码或者其他方式使查询条件落在有索引的列上,至少要让有索引的列出现在查询条件中,海量数据查询不走索引这是...我也不知说什么好了。另外不要使用任何mysql函数,会使索引无效而进行全表扫描

#5


我来说两句吧

首先,第一句:
select嵌套,一先把所有2017-11-22的distinct的phone找出来,然后再count,或者先count,再distinct

当然,重点第二句:
换SSD!换SSD!换SSD!

尼玛我曾今抓破脑子想优化,有毛线用,换了个SSD,那酸爽.....哎,真是钱花到哪好到哪...

#6


where DATE_FORMAT(DATE,'%Y-%m-%d') = '2017-11-22';  这样肯定全表扫描。字段不要用函数,重要的说3遍

#7


我建议你分两步:第一步建date 索引;
第二步:修改一下my.ini配置文件,innodb_buffer_pool_size 增大这个数值,同时logfile也要增大,这样你的时间会缩短。

我用相同的数据测试了一下,我用了443.31秒,因为我的硬件是笔记本2G内存,如果是服务器时间可以更短。

#8


感谢各位大神们的回复,已结贴给分