我们有几个 MySql 查询,当选择较少数量的记录时(即限制为 0,100),它们表现良好。
当我们将限制从 100 增加到 1000(即限制 0,1000)时,查询花费的时间几乎增加了 10 倍到 50 倍。
已编辑 我们如何优化它?解释计划在下面给出,
查询
Select
concat(floor(TIMESTAMPDIFF(MINUTE,x.msgCreatedOn, NOW())/60),':',floor(TIMESTAMPDIFF(MINUTE,x.msgCreatedOn, NOW())%60)) as aging,
x.`actionStartDate`,
concat(floor(TIMESTAMPDIFF(MINUTE,x.`actionStartDate`, NOW())/60),':',floor(TIMESTAMPDIFF(MINUTE,x.`actionStartDate`, NOW())%60)) as workflowAging
from
(
Select
*
from
t_wk_dtls d left
join t_s_dtls s on (d.id = s.`work_parentId` or d.`parentId` = s.`work_parentId`) and d.`currentlyActive` = true
left join t_w b on b.basketId=d.toBasketId
left join t_u u on d.toUserId= u.userId
left join t_s_m sch on d.sourceId=sch.schMsgId
left join t_l_s_a a on a.orgId='1002'
AND ((((a.`type`='TWITTER' and d.channel in (1,34))
or (a.`type`='FACEBOOK' and d.channel in (6,7))
or (a.`type`='GOOGLEPLUS' and d.channel in (5,25))
or (a.`type`='LINKEDIN' and d.channel =30)
or (a.`type`='GOOGLEPLUS' and d.channel=36)
or ((a.`type`='YOUTUBE' or a.`type`='GOOGLEPLUS') and d.channel=27)
or (a.`type`='TUMBLR' and d.channel in (29,31))
or (a.`type`='INSTAGRAM' and d.channel=35) ) AND d.userChannelId=a.socialId) OR (a.`type`='BLOG' and d.channel in (9,11,15,21) AND d.msgId=a.socialId))
left join t_l l on l.leadId=a.leadId and l.orgId='1002'
where
d.currentlyActive = true
and d.dataSource ='SOLR'
and d.profileId = '148' AND msgCreatedOn BETWEEN '2016-03-14 18:30:00' AND '2016-03-31 18:29:59'
order by d.msgCreatedOn desc limit 0,100000 ) as x
最佳答案
你真的需要一个子查询吗?现在,请注意解释结果中的“依赖子查询”——它通常意味着子查询对每个返回的外部行执行一次(参见 point 18.2.1.18.2 in "18.2.1.18 Subquery optimization" )。因此,随着返回的行越来越多,您的执行时间呈指数级增长。
因为您只是在子查询中执行 select * from
,这样的事情不会完成同样的事情吗?
Select
concat(floor(TIMESTAMPDIFF(MINUTE,x.msgCreatedOn, NOW())/60),':',floor(TIMESTAMPDIFF(MINUTE,x.msgCreatedOn, NOW())%60)) as aging,
x.`actionStartDate`,
concat(floor(TIMESTAMPDIFF(MINUTE,x.`actionStartDate`, NOW())/60),':',floor(TIMESTAMPDIFF(MINUTE,x.`actionStartDate`, NOW())%60)) as workflowAging
from
t_wk_dtls d left
join t_s_dtls s on (d.id = s.`work_parentId` or d.`parentId` = s.`work_parentId`) and d.`currentlyActive` = true
left join t_w b on b.basketId=d.toBasketId
left join t_u u on d.toUserId= u.userId
left join t_s_m sch on d.sourceId=sch.schMsgId
left join t_l_s_a a on a.orgId='1002'
AND ((((a.`type`='TWITTER' and d.channel in (1,34))
or (a.`type`='FACEBOOK' and d.channel in (6,7))
or (a.`type`='GOOGLEPLUS' and d.channel in (5,25))
or (a.`type`='LINKEDIN' and d.channel =30)
or (a.`type`='GOOGLEPLUS' and d.channel=36)
or ((a.`type`='YOUTUBE' or a.`type`='GOOGLEPLUS') and d.channel=27)
or (a.`type`='TUMBLR' and d.channel in (29,31))
or (a.`type`='INSTAGRAM' and d.channel=35) ) AND d.userChannelId=a.socialId) OR (a.`type`='BLOG' and d.channel in (9,11,15,21) AND d.msgId=a.socialId))
left join t_l l on l.leadId=a.leadId and l.orgId='1002'
where
d.currentlyActive = true
and d.dataSource ='SOLR'
and d.profileId = '148' AND msgCreatedOn BETWEEN '2016-03-14 18:30:00' AND '2016-03-31 18:29:59'
order by d.msgCreatedOn desc limit 0,100000;
(除了开头的列列表中的表前缀由“x”改为真实的)
关于Mysql需要很长时间才能达到更大的限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36352295/