如何优化这个IF-MySQL查询
此MySQL查询运行时间超过6分钟。瓶颈是生成“活动完成”列的最后一块。我之所以将其编写为子查询,是因为如果itemtype=“course”,我需要查找每个类中每个用户的所有其他项类型的最大日期,而不是整个表列的最大日期。我肯定有更好的办法,但我不知道是什么。有人能帮我吗如何优化这个IF-MySQL查询,mysql,optimization,Mysql,Optimization,此MySQL查询运行时间超过6分钟。瓶颈是生成“活动完成”列的最后一块。我之所以将其编写为子查询,是因为如果itemtype=“course”,我需要查找每个类中每个用户的所有其他项类型的最大日期,而不是整个表列的最大日期。我肯定有更好的办法,但我不知道是什么。有人能帮我吗 SELECT DISTINCT u.firstname AS 'First' , u.lastname AS 'Last', c.fullname AS 'Course', IF (gi.itemtype = '
SELECT DISTINCT
u.firstname AS 'First' , u.lastname AS 'Last', c.fullname AS 'Course',
IF (gi.itemtype = 'course',
CONCAT(c.fullname," COURSE TOTAL"),
gi.itemname) AS 'Item Name',
IFNULL(CONCAT(ROUND(gg.finalgrade,2),'/',ROUND(gi.grademax,2)), '0')
AS 'Points Earned',
IFNULL(CONCAT(ROUND((gg.finalgrade/gi.grademax),2)*100,'%'), '0%')
AS 'Percentage',
(SELECT
IF(`Percentage`>=90, 'A',
IF(`Percentage`<90 AND `Percentage`>=80, 'B',
IF(`Percentage`<80 AND `Percentage`>=70, 'C',
IF(`Percentage`<70 AND `Percentage`>=60, 'D', 'F')))))
AS 'Grade',
IF(gi.itemtype = 'course',
(SELECT
FROM_UNIXTIME(GREATEST(MAX(gg.timemodified), MAX(gg.timecreated)),
'%m/%d/%Y')
FROM mdl_course c
JOIN mdl_grade_items gi
JOIN mdl_grade_grades gg
WHERE gg.userid=u.id
AND gi.courseid=c.id),
CASE
WHEN gg.timecreated IS NULL AND gg.timemodified IS NULL THEN '-'
WHEN gg.timecreated IS NULL AND gg.timemodified IS NOT NULL THEN FROM_UNIXTIME(gg.timemodified, '%m/%d/%Y')
WHEN gg.timecreated IS NOT NULL AND gg.timemodified IS NULL THEN FROM_UNIXTIME(gg.timecreated, '%m/%d/%Y')
WHEN gg.timecreated<=gg.timemodified THEN FROM_UNIXTIME(gg.timemodified,'%m/%d/%Y')
END)
AS 'Activity Completed'
FROM mdl_user u
JOIN mdl_user_enrolments ue on ue.userid=u.id
JOIN mdl_enrol e ON e.id=ue.enrolid
JOIN mdl_course c on c.id = e.courseid
JOIN mdl_context AS ctx ON ctx.instanceid = c.id
JOIN mdl_role_assignments AS ra ON ra.contextid = ctx.id
JOIN mdl_role AS r ON r.id = e.roleid
JOIN mdl_grade_items AS gi ON gi.courseid=c.id
LEFT JOIN mdl_grade_grades AS gg ON gg.userid=u.id
AND gg.itemid=gi.id
WHERE ue.status='0'
AND gi.hidden = '0'
AND gi.itemtype <> 'category'
AND gg.excluded = '0'
OR gg.excluded IS NULL
ORDER BY u.lastname, c.fullname, gi.itemtype DESC, gi.sortorder ASC
这就是我在向查询解释之前得到的结果。
我无法复制列标题。它们是:
id, select_type, table, type, possible_keys, key, key_len, ref, rows, extra
1 PRIMARY u ALL PRIMARY 449 Using temporary; Using filesort
1 PRIMARY ue ref mdl_userenro_enruse_uix,mdl_userenro_enr_ix,mdl_userenro_use_ix mdl_userenro_use_ix 8 skol_dev.u.id 1 Using where
1 PRIMARY e eq_ref PRIMARY,mdl_enro_cou_ix PRIMARY 8 skol_dev.ue.enrolid 1
1 PRIMARY r eq_ref PRIMARY PRIMARY 8 skol_dev.e.roleid 1 Using index
1 PRIMARY c eq_ref PRIMARY PRIMARY 8 skol_dev.e.courseid 1
1 PRIMARY ctx ref PRIMARY,mdl_cont_ins_ix mdl_cont_ins_ix 8 skol_dev.c.id 1 Using where; Using index
1 PRIMARY gi ref mdl_graditem_itenee_ix,mdl_graditem_cou_ix mdl_graditem_cou_ix 9 skol_dev.e.courseid 7 Using where
1 PRIMARY ra ref mdl_roleassi_con_ix mdl_roleassi_con_ix 8 skol_dev.ctx.id 4 Using index
1 PRIMARY gg eq_ref mdl_gradgrad_useite_uix,mdl_gradgrad_ite_ix,mdl_gradgrad_use_ix mdl_gradgrad_useite_uix 16 skol_dev.u.id,skol_dev.gi.id 1 Using where
3 DEPENDENT SUBQUERY gg ref mdl_gradgrad_useite_uix,mdl_gradgrad_use_ix mdl_gradgrad_use_ix 8 skol_dev.u.id 6
3 DEPENDENT SUBQUERY c index PRIMARY mdl_cour_cat_ix 8 124 Using index; Using join buffer
3 DEPENDENT SUBQUERY gi ref mdl_graditem_cou_ix mdl_graditem_cou_ix 9 skol_dev.c.id 7 Using where; Using index
将
EXPLAIN
预先添加到完整查询中(即EXPLAIN-SELECT…
),将其交给MySQL引擎,并将结果编辑到您的问题中。如果不知道查询优化器正在对查询执行什么操作,就不可能提供结论性的答案。如果没有直接的答案,我认为您需要在(gg.excluded='0'或gg.excluded为NULL)周围使用paren。否则,一旦一个条目具有gg,您的所有ue和gi条件都将被忽略。excluded为NULL。此外,除了加入之外,您对CTX、RA和R表不做任何操作。您可能会从查询中完全删除这些内容。。。如果有人报名参加某个课程,谁会在乎“角色分配”是谁呢。谢谢,亚伦,我已经在我的问题中添加了解释部分。谢谢,德拉普指出了失踪的帕伦夫妇。额外的表包括在内,因为我将添加更多的WHERE语句,以便报告中只包括学生。查看解释结果,我意识到我没有指明要在哪些字段上加入子查询表,所以我修复了这个问题。然后我改变了加入子查询表的顺序,现在我只剩下9秒了。我可以接受。:-)谢谢你的解释建议!
id, select_type, table, type, possible_keys, key, key_len, ref, rows, extra
1 PRIMARY u ALL PRIMARY 449 Using temporary; Using filesort
1 PRIMARY ue ref mdl_userenro_enruse_uix,mdl_userenro_enr_ix,mdl_userenro_use_ix mdl_userenro_use_ix 8 skol_dev.u.id 1 Using where
1 PRIMARY e eq_ref PRIMARY,mdl_enro_cou_ix PRIMARY 8 skol_dev.ue.enrolid 1
1 PRIMARY r eq_ref PRIMARY PRIMARY 8 skol_dev.e.roleid 1 Using index
1 PRIMARY c eq_ref PRIMARY PRIMARY 8 skol_dev.e.courseid 1
1 PRIMARY ctx ref PRIMARY,mdl_cont_ins_ix mdl_cont_ins_ix 8 skol_dev.c.id 1 Using where; Using index
1 PRIMARY gi ref mdl_graditem_itenee_ix,mdl_graditem_cou_ix mdl_graditem_cou_ix 9 skol_dev.e.courseid 7 Using where
1 PRIMARY ra ref mdl_roleassi_con_ix mdl_roleassi_con_ix 8 skol_dev.ctx.id 4 Using index
1 PRIMARY gg eq_ref mdl_gradgrad_useite_uix,mdl_gradgrad_ite_ix,mdl_gradgrad_use_ix mdl_gradgrad_useite_uix 16 skol_dev.u.id,skol_dev.gi.id 1 Using where
3 DEPENDENT SUBQUERY gg ref mdl_gradgrad_useite_uix,mdl_gradgrad_use_ix mdl_gradgrad_use_ix 8 skol_dev.u.id 6
3 DEPENDENT SUBQUERY c index PRIMARY mdl_cour_cat_ix 8 124 Using index; Using join buffer
3 DEPENDENT SUBQUERY gi ref mdl_graditem_cou_ix mdl_graditem_cou_ix 9 skol_dev.c.id 7 Using where; Using index