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 感觉改写难度要大很多?
5 个解决方案
#1
和上次的一样。除了今天的,其余的统计每天晚上先生成。
#2
有点困惑 count(distinct(ul.userId))
WHEN (ul.lastaccess>subdate(curdate(),1) and ul.lastaccess <curdate()) THEN 等
还是头疼不知道如何转化?
WHEN (ul.lastaccess>subdate(curdate(),1) and ul.lastaccess <curdate()) THEN 等
还是头疼不知道如何转化?
#3
你要统计的不过是
本日,昨日,本月,上月
有多少不同名的用户登录。
你每天晚上定时 12:00am 生成这个数据 ( 昨日, 上月)
然后只需要统计 今天和 本月的就行了!
建议基于 lastaccess 的索引
本日,昨日,本月,上月
有多少不同名的用户登录。
你每天晚上定时 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
#4
明白了 大致写如下
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'
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
解决 感谢 楼上
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'
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
解决 感谢 楼上
#5
上面的语句测试是ok的
count(distinct 可以替换为 group by id
数据库设计其实可以改写的哦 (但项目已经上线 不要随便更改)
count(distinct 可以替换为 group by id
数据库设计其实可以改写的哦 (但项目已经上线 不要随便更改)
#1
和上次的一样。除了今天的,其余的统计每天晚上先生成。
#2
有点困惑 count(distinct(ul.userId))
WHEN (ul.lastaccess>subdate(curdate(),1) and ul.lastaccess <curdate()) THEN 等
还是头疼不知道如何转化?
WHEN (ul.lastaccess>subdate(curdate(),1) and ul.lastaccess <curdate()) THEN 等
还是头疼不知道如何转化?
#3
你要统计的不过是
本日,昨日,本月,上月
有多少不同名的用户登录。
你每天晚上定时 12:00am 生成这个数据 ( 昨日, 上月)
然后只需要统计 今天和 本月的就行了!
建议基于 lastaccess 的索引
本日,昨日,本月,上月
有多少不同名的用户登录。
你每天晚上定时 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
#4
明白了 大致写如下
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'
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
解决 感谢 楼上
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'
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
解决 感谢 楼上
#5
上面的语句测试是ok的
count(distinct 可以替换为 group by id
数据库设计其实可以改写的哦 (但项目已经上线 不要随便更改)
count(distinct 可以替换为 group by id
数据库设计其实可以改写的哦 (但项目已经上线 不要随便更改)