简单MySQL子查询性能
考虑以下两个MySQL查询:简单MySQL子查询性能,mysql,performance,optimization,Mysql,Performance,Optimization,考虑以下两个MySQL查询: SELECT ue.userid,e.courseid FROM (SELECT id,courseid FROM mdl_enrol WHERE status = 0 AND courseid IN (46)) e INNER JOIN (SELECT enrolid,userid FROM mdl_user_enrolments ) ue ON ue.enrolid = e.id INNER JOIN (SELECT userid FROM mdl_use
SELECT ue.userid,e.courseid
FROM (SELECT id,courseid FROM mdl_enrol WHERE status = 0 AND courseid IN (46)) e
INNER JOIN (SELECT enrolid,userid FROM mdl_user_enrolments ) ue ON ue.enrolid = e.id
INNER JOIN (SELECT userid FROM mdl_userdata) ud ON ue.userid = ud.userid
-
底部查询比顶部查询快得多,但为什么呢?我已经读到,为了提高性能,您应该只选择您需要的列。另外,对我来说,最上面的查询应该执行得更好,因为在每次连接中,您都在减少连接的数据量。显然,我对数据库工作原理的理解是错误的,但如果有人能澄清这一点,我将不胜感激。解释也证实了底部查询要快得多
非常感谢。在第一个查询中,mysql应该从mdl_enrol表中选择一个子集,并将mdl_user_enrol和mdl_userdata填写到内存中。所以你在内存中选择了很多数据。完成后,您将加入数据。如果没有足够的内存来放置所有数据,直到数据被连接并发送回客户机,那么就会在硬盘上创建临时表。很可能mysql优化器不够酷,无法修复错误并尝试改进执行计划。这就是它慢的原因
而对于第二个查询,mysql知道它需要选择什么,只选择少量必需的数据。在这个场景中,假设已经创建了所有必要的索引,就可以使用索引。所以它很快。在第一个查询中,mysql应该从mdl_enrol表中选择一个子集,并将mdl_user_enrol和mdl_userdata完成到内存中。所以你在内存中选择了很多数据。完成后,您将加入数据。如果没有足够的内存来放置所有数据,直到数据被连接并发送回客户机,那么就会在硬盘上创建临时表。很可能mysql优化器不够酷,无法修复错误并尝试改进执行计划。这就是它慢的原因
而对于第二个查询,mysql知道它需要选择什么,只选择少量必需的数据。在这个场景中,假设已经创建了所有必要的索引,就可以使用索引。所以它很快。要提高性能,您应该只选择您需要的列;要提高性能,您应该避免使用子查询:-要提高性能,您应该只选择您需要的列;要提高性能,您应该避免使用子查询:-感谢您的回复。因此,基本上,如果避免子查询,MySQL在内存已满时不太可能需要创建临时表。而且,当使用子查询时,索引的效率较低,或者根本没有效率?@paul78:有一些近似值-是的。查询优化过程非常困难,但避免子查询是一个很好的经验法则。虽然子查询有一些有效的例子,但这是另一回事-谢谢你的回复。因此,基本上,如果避免子查询,MySQL在内存已满时不太可能需要创建临时表。而且,当使用子查询时,索引的效率较低,或者根本没有效率?@paul78:有一些近似值-是的。查询优化过程非常困难,但避免子查询是一个很好的经验法则。虽然子查询有一些有效的例子,但这是另一回事-
SELECT ue.userid,e.courseid
FROM mdl_enrol e
INNER JOIN mdl_user_enrolments ue ON ue.enrolid = e.id
INNER JOIN mdl_userdata ud ON ue.userid = ud.userid
WHERE e.status = 0 AND e.courseid IN (46)