我创建了一个带有多个连接的查询,用于从多个表中获取数据。对于5000多条记录,它的工作速度非常慢。我检查过并为查询中使用的每个表正确设置了索引。我尝试使用多个选项优化此查询,但它不起作用,我不完全理解EXPLAIN或EXPLAIN EXTENDED帮助。
=====
EXPLAIN EXTENDED
SELECT @rownum := @rownum + 1 AS id,
u.id AS userid,
u.username AS employeeid,
u.firstname,
u.lastname,
u.email AS email,
u.city AS state,
c.fullname AS course,
c.id AS courseid,
c.fullname AS coursename,
fi2.data branchid,
fi3.data branchname,
fi6.data areaname,
fi7.data regname,
fi8.data designation,
fi9.data department,
fi10.data zone,
fi11.data branchcategory,
fi12.data branchdistrict,
fi13.data branchstate,
fi17.data gender,
fi21.data employeecategory,
fi22.data persontype,
fi23.data assignmentstatus,
fi30.data POSITION,
fi32.data dateofjoining,
fi33.data dateofbirth,
st.scoid,
st.scormid,
st.attempt,
st.value cmistarttime,
st5.value cmilessonstatus,
st5.timemodified cmitimemodified,
st3.value cmitotaltime,
st2.value cmiscore
FROM (
SELECT @rownum := 0
) r,
mdl_user u
JOIN mdl_role_assignments ra ON ra.userid = u.id
JOIN mdl_context ctx ON ctx.id = ra.contextid
JOIN mdl_course c ON c.id = ctx.instanceid
JOIN mdl_scorm s ON s.course = c.id
JOIN mdl_scorm_scoes_track st ON st.scormid = s.id AND st.userid = u.id
JOIN mdl_scorm_scoes_track AS st2 ON (u.id = st2.userid AND st2.scormid
= s.id AND st2.scoid = st.scoid AND st2.attempt = st.attempt)
JOIN mdl_scorm_scoes_track AS st3 ON (u.id = st3.userid AND st3.scormid
= s.id AND st3.scoid = st.scoid AND st3.attempt = st.attempt)
JOIN mdl_scorm_scoes_track AS st5 ON (u.id = st5.userid AND st5.scormid
= s.id AND st5.scoid = st.scoid AND st5.attempt = st.attempt)
JOIN mdl_user_info_data AS fi2 ON u.id = fi2.userid
JOIN mdl_user_info_data AS fi3 ON u.id = fi3.userid
JOIN mdl_user_info_data AS fi6 ON u.id = fi6.userid
JOIN mdl_user_info_data AS fi7 ON u.id = fi7.userid
JOIN mdl_user_info_data AS fi8 ON u.id = fi8.userid
JOIN mdl_user_info_data AS fi9 ON u.id = fi9.userid
JOIN mdl_user_info_data AS fi10 ON u.id = fi10.userid
JOIN mdl_user_info_data AS fi11 ON u.id = fi11.userid
JOIN mdl_user_info_data AS fi12 ON u.id = fi12.userid
JOIN mdl_user_info_data AS fi13 ON u.id = fi13.userid
JOIN mdl_user_info_data AS fi17 ON u.id = fi17.userid
JOIN mdl_user_info_data AS fi21 ON u.id = fi21.userid
JOIN mdl_user_info_data AS fi22 ON u.id = fi22.userid
JOIN mdl_user_info_data AS fi23 ON u.id = fi23.userid
JOIN mdl_user_info_data AS fi30 ON u.id = fi30.userid
JOIN mdl_user_info_data AS fi32 ON u.id = fi32.userid
JOIN mdl_user_info_data AS fi33 ON u.id = fi33.userid
WHERE c.id > 0 AND
u.id > 0 AND
u.deleted = 0 AND
u.suspended = 0 AND
u.confirmed = 1 AND
u.id <= 1000 AND
c.visible = 1 AND
st.element LIKE '%x.start.time%' AND
st2.element LIKE '%cmi.core.score.raw%' AND
st3.element LIKE '%cmi.core.total_time%' AND
st5.element LIKE '%cmi.core.lesson_status%' AND
fi2.fieldid = 2 AND
fi3.fieldid = 3 AND
fi6.fieldid = 6 AND
fi7.fieldid = 7 AND
fi8.fieldid = 8 AND
fi9.fieldid = 9 AND
fi10.fieldid = 10 AND
fi11.fieldid = 11 AND
fi12.fieldid = 12 AND
fi13.fieldid = 13 AND
fi17.fieldid = 17 AND
fi21.fieldid = 21 AND
fi22.fieldid = 22 AND
fi23.fieldid = 23 AND
fi30.fieldid = 30 AND
fi32.fieldid = 32 AND
fi33.fieldid = 33 AND
ra.roleid = 5 AND
ctx.contextlevel = 50
==========================
答案 0 :(得分:0)
你的四向自连接的目的似乎粗略地说明了4行涉及相同的userid-scormid-scoid-attempt但有4个不同的元素。这是获得4元素出现的4元组的昂贵方法。 (此外,这5列形成一个唯一键。)阅读关系分区,它找到具有子行值的行,这些行与另一个表中的所有子行值一起出现,并在SQL中表示。例如,您希望每个4元组的组具有不同的元素计数= 4,其中元素属于4个值。
答案 1 :(得分:0)
是的,你的假设是正确的。以下是我的轻量级查询。这是4向自连接,但具有不同的元素。这是标准表并存储了14,00,000多条记录,因此我很难更改表结构或插入查询。
SELECT DISTINCT st1.* FROM mdl_scorm_scoes_track st1
JOIN mdl_scorm_scoes_track st2 ON st1.userid = st2.userid AND st1.scormid = st2.scormid AND st1.scoid = st2.scoid AND st1.attempt = st2.attempt
JOIN mdl_scorm_scoes_track st3 ON st1.userid = st3.userid AND st1.scormid = st3.scormid AND st1.scoid = st3.scoid AND st1.attempt = st3.attempt
JOIN mdl_scorm_scoes_track st4 ON st1.userid = st4.userid AND st1.scormid = st4.scormid AND st1.scoid = st4.scoid AND st1.attempt = st4.attempt
AND st1.element = 'x.start.time'
AND st2.element = 'cmi.core.score.raw'
AND st3.element = 'cmi.core.total_time'
AND st4.element = 'cmi.core.lesson_status' AND st1.userid <= 10
GROUP BY st1.userid, st1.scormid, st1.scoid, st1.attempt
我也尝试过你建议的方法,但没有用。如果我的查询中有任何问题,请检查并告诉我
SELECT DISTINCT st1.* FROM mdl_scorm_scoes_track st1
JOIN mdl_scorm_scoes_track st2 ON st1.userid = st2.userid AND st1.scormid = st2.scormid AND st1.scoid = st2.scoid AND st1.attempt = st2.attempt
JOIN mdl_scorm_scoes_track st3 ON st1.userid = st3.userid AND st1.scormid = st3.scormid AND st1.scoid = st3.scoid AND st1.attempt = st3.attempt
JOIN mdl_scorm_scoes_track st4 ON st1.userid = st4.userid AND st1.scormid = st4.scormid AND st1.scoid = st4.scoid AND st1.attempt = st4.attempt
AND st1.element = 'x.start.time'
AND st2.element = 'cmi.core.score.raw'
AND st3.element = 'cmi.core.total_time'
AND st4.element = 'cmi.core.lesson_status' AND st1.userid <= 10
GROUP BY st1.userid, st1.scormid, st1.scoid, st1.attempt
HAVING COUNT(*) = (
SELECT COUNT(*) FROM mdl_scorm_scoes_track st5
WHERE st1.userid = st5.userid AND st1.scormid = st5.scormid AND st1.scoid = st5.scoid AND st1.attempt = st5.attempt AND st5.element = 'x.start.time'
)