我有2张桌子 hudges 和 hentry
hjudges表显示每个事件ID,类别,时间,日期
jeid (primary) | jcategory | jtimeofday | jedate
101 |beginner |AM|2020-01-01|
101 |intermediate|AM|2020-01-01|
101 |advanced |AM|2020-01-01|
102 |beginner |AM|2020-01-05|
102 |intermediate|AM|2020-01-05|
102 |advanced |AM|2020-01-05|
hentry表显示“输入”该事件的用户。 (为了简化起见,省略了一些信息)
hentryid (primary)|heid | hcategory | htimeofday | hedate | huserid | hstatus | hedtime
1| 101 | beginner |AM|2020-01-01| 5 |active | 2019-12-05 12:00:00
2| 101 | intermediate |AM|2020-01-01| 5 |active | 2019-12-05 12:00:00
3| 101 | beginner |AM|2020-01-01| 6 |active | 2019-12-05 12:00:00
4| 101 | intermediate |AM|2020-01-01| 6 |active | 2019-12-05 12:00:00
由于事件有限,当人们输入时,我要对条目进行计数。
以下查询有效,但是非常慢。这需要9秒钟或更长时间。
select
ei.jcategory as jcategory,
ei.jtimeofday as jtimeofday ,
ei.jedate as jedate,
(select count(*) from hentry e where e.heid =ei.jeid and e.hcategory = ei.jcategory and ei.jedate = e.hedate and ei.jtimeofday = e.htimeofday
and (((e.hstatus = 'pending' or e.hstatus = 'npending') and e.hedtime <= DATE_SUB(NOW(), INTERVAL 500000 MICROSECOND) and e.huserid <> '5' ) OR (e.hstatus = 'active')) ) as count
from hjudges ei where ei.jeid = '101'
group by ei.jedate, ei.jtimeofday, ei.jcategory
下面是结果,但是可能要花很长时间,具体取决于查询。
jcategory |jtimeofday|jedate | count
beginner |AM |2020-01-01| 2
intermediate|AM |2020-01-01| 2
advanced |AM |2020-01-01| 0
我能够创建一些替代的联接查询,但是要么无法正确计数,要么对于高级级别不显示0。因为条目表中没有任何条目。
需要帮助。
答案 0 :(得分:1)
您是否可以尝试联接表,而不是像这样进行子查询:
SELECT ei.jcategory AS jcategory,
ei.jtimeofday AS jtimeofday ,
ei.jedate AS jedate,
count(*)
FROM hjudges ei
LEFT JOIN hentry e on e.heid =ei.jeid
AND e.hcategory = ei.jcategory
AND ei.jedate = e.hedate
AND ei.jtimeofday = e.htimeofday
AND (e.hstatus = 'active'
OR
(e.hstatus in ('pending', 'npending') AND e.hedtime <= DATE_SUB(NOW(), INTERVAL 500000 MICROSECOND) AND e.huserid <> '5'))
AND ei.jeid = '101'
GROUP BY ei.jedate,
ei.jtimeofday,
ei.jcategory
还要在hstatus,hedtime和huserid上创建索引,然后运行查询。还有其他解决方法,例如将查询分为两个。如果查询很短,我会在评论中添加它。
当您执行建议的explain select...
之类的nbk
时,MySQL会告诉您所使用的索引。您可以为查询提供提示,以使用与其选择的索引不同的索引。为此,请参见https://dev.mysql.com/doc/refman/5.7/en/index-hints.html。
您可以将查询分为2个-一个的hstatus为active状态,另一个为其他hstatuses。
select jcategory, jtimeofday, jedate, sum(totals)
from
(
SELECT ei.jcategory AS jcategory,
ei.jtimeofday AS jtimeofday ,
ei.jedate AS jedate,
count(*) as totals
FROM hjudges ei
LEFT JOIN hentry e on e.heid =ei.jeid
AND e.hcategory = ei.jcategory
AND ei.jedate = e.hedate
AND ei.jtimeofday = e.htimeofday
AND e.hstatus = 'active'
AND ei.jeid = '101'
GROUP BY ei.jedate,
ei.jtimeofday,
ei.jcategory
union all
SELECT ei.jcategory AS jcategory,
ei.jtimeofday AS jtimeofday ,
ei.jedate AS jedate,
count(*) as totals
FROM hjudges ei
LEFT JOIN hentry e on e.heid =ei.jeid
AND e.hcategory = ei.jcategory
AND ei.jedate = e.hedate
AND ei.jtimeofday = e.htimeofday
AND e.hstatus in ('pending', 'npending')
AND e.hedtime <= DATE_SUB(NOW(), INTERVAL 500000 MICROSECOND)
AND e.huserid <> '5'
AND ei.jeid = '101'
GROUP BY ei.jedate,
ei.jtimeofday,
ei.jcategory
) x
group by jcategory, jtimeofday, jedate
这将使您可以注释掉两个查询中的一个,以分别研究性能,并找出哪个是瓶颈以及为什么,以及为使其运行更快而设置什么样的索引。