最近,我在研究opencart源代码,发现使用的是子查询而不是LEFT JOIN。
Opencart v3 在文件admin / model / user / user.php上查看它
$query = "SELECT *, (
SELECT ug.name
FROM `" . DB_PREFIX . "user_group` ug
WHERE ug.user_group_id = u.user_group_id
) AS user_group
FROM `" . DB_PREFIX . "user` u
WHERE u.user_id = '" . (int)$user_id . "'";
我会这样使用
$query = "SELECT u.*, ug.name AS user_group
FROM `" . DB_PREFIX . "user` u
LEFT JOIN `" . DB_PREFIX . "user_group` ug ON ug.user_group_id = u.user_group_id
WHERE u.user_id = '" . (int)$user_id . "'";
我的问题是,使用“选择”列中的子查询是否可以提高性能?如果是,怎么办?如果否,那么为什么这个主要社区正在使用这种方式? 我也发现他们没有使用外键,为什么?
答案 0 :(得分:1)
当外部查询正在处理大量行时,相关子查询可能会成为性能问题;因为子查询会针对每一行执行。
此查询看起来最多返回一行,因为user_id
是唯一的键。由于外部查询最多返回单行,因此子查询将仅执行一次。
看起来user_group_id
是user_group
表中的唯一键,因此子查询最多返回一行。 (在更一般的情况下,如果子查询返回的行多于该行,我们将得到一个错误。使用LEFT JOIN,我们将获得多行返回。)
问:使用“选择”列中的子查询是否可以提高性能?
A:任何一种形式都不会影响性能。带有相关子查询的表单可能更快,但差异并不明显。
问:如果可以,怎么办?如果没有,那么为什么这个主要社区正在使用这种方式?
A:这是有效的SQL,可以正常工作,没有动力进行更改。
问:我也发现他们没有使用外键,为什么?
A:不需要RDBMS强制执行参照完整性;如果应用程序正在处理它,那么我们可以避免数据库的开销。
某些存储引擎(例如MyISAM)不强制执行外键约束。
外键有时会干扰管理操作,例如清空和重新加载表。
所有的设计决定;有多种方法可以给猫皮。 (我们只是在这里略读一遍;更深入地潜水将更多地基于观点,从而为哪种方法使猫皮更好是一个论点。)