昨天得到一个慢查询的解决思路,今天又找了一个困扰更长时间的sql
mysql 在linux 下 版本5.0以上
当SessionLog 数量小的左右的时候,这个sql 执行时间速度还可以的
select count(distinct(ul.userId)) number,
CASE WHEN ul.lastaccess>curdate() THEN 1
WHEN (ul.lastaccess>subdate(curdate(),1) and ul.lastaccess<curdate()) THEN 2
WHEN (ul.lastaccess>date_Sub(curdate(), INTERVAL DAYOFMONTH(curdate())-1 day)) THEN 3
WHEN (ul.lastaccess>date_sub(date_Sub(curdate(), INTERVAL DAYOFMONTH(curdate())-1 day),INTERVAL 1 month) and ul.lastaccess<DATE_SUB(sysdate(),INTERVAL 1 month)) THEN 4
ELSE 5 END as Interval from SessionLog ul,User u where u.id = ul.userid group by Interval;
但是现在几个月来,SessionLog 增长到300万,发现慢,高达43秒,实在是太慢。 而且这个表几乎每天必用,一天用好多次的。
我已经对这个表加了索引 ,问该如何才能提升sql的速度?? 我在按照昨天的方法进行加临时表 用union all联合进行查询加快查询速度。
但是count(distinct 感觉改写难度要大很多?
mysql 在linux 下 版本5.0以上
当SessionLog 数量小的左右的时候,这个sql 执行时间速度还可以的
select count(distinct(ul.userId)) number,
CASE WHEN ul.lastaccess>curdate() THEN 1
WHEN (ul.lastaccess>subdate(curdate(),1) and ul.lastaccess<curdate()) THEN 2
WHEN (ul.lastaccess>date_Sub(curdate(), INTERVAL DAYOFMONTH(curdate())-1 day)) THEN 3
WHEN (ul.lastaccess>date_sub(date_Sub(curdate(), INTERVAL DAYOFMONTH(curdate())-1 day),INTERVAL 1 month) and ul.lastaccess<DATE_SUB(sysdate(),INTERVAL 1 month)) THEN 4
ELSE 5 END as Interval from SessionLog ul,User u where u.id = ul.userid group by Interval;
但是现在几个月来,SessionLog 增长到300万,发现慢,高达43秒,实在是太慢。 而且这个表几乎每天必用,一天用好多次的。
我已经对这个表加了索引 ,问该如何才能提升sql的速度?? 我在按照昨天的方法进行加临时表 用union all联合进行查询加快查询速度。
但是count(distinct 感觉改写难度要大很多?
还是头疼不知道如何转化?
有多少不同名的用户登录。你每天晚上定时 12:00am 生成这个数据 (昨日,上月)
然后只需要统计今天和本月的就行了!建议基于 lastaccess 的索引select
(select count(distinct userid) from SessionLog where lastaccess>=curdate()) as `number`,
1 as `Interval`
union all
select
(select count(distinct userid) from SessionLog where lastaccess>=select curdate()-INTERVAL (day(curdate())-1) day ) as `number`,
3 as `Interval`
union all
select * from xxxxxxxxxx
CASE WHEN ul.lastaccess>curdate() THEN 1
WHEN (ul.lastaccess>subdate(curdate(),1) and ul.lastaccess <curdate()) THEN 2
WHEN (ul.lastaccess>date_Sub(curdate(), INTERVAL DAYOFMONTH(curdate())-1 day)) THEN 3
WHEN (ul.lastaccess>date_sub(date_Sub(curdate(), INTERVAL DAYOFMONTH(curdate())-1 day),INTERVAL 1 month) and ul.lastaccess <DATE_SUB(sysdate(),INTERVAL 1 month)) THEN 4
ELSE 5 END as Interval from SessionLog ul,User u where u.id = ul.userid
and ul.lastaccess<'2009-11-01'union all
select count(distinct(ul.userId)) number,
CASE WHEN ul.lastaccess>curdate() THEN 1
WHEN (ul.lastaccess>subdate(curdate(),1) and ul.lastaccess <curdate()) THEN 2
WHEN (ul.lastaccess>date_Sub(curdate(), INTERVAL DAYOFMONTH(curdate())-1 day)) THEN 3
WHEN (ul.lastaccess>date_sub(date_Sub(curdate(), INTERVAL DAYOFMONTH(curdate())-1 day),INTERVAL 1 month) and ul.lastaccess <DATE_SUB(sysdate(),INTERVAL 1 month)) THEN 4
ELSE 5 END as Interval from SessionLog ul,User u where u.id = ul.userid
and ul.lastaccess>'2009-11-01 00:00:00'group by Interval解决 感谢 楼上
数据库设计其实可以改写的哦 (但项目已经上线 不要随便更改)