为什么OpenCart使用Subquery而不是LEFT JOIN?

时间:2019-03-14 15:02:50

标签: mysql mysqli opencart opencart-3

最近,我在研究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 . "'";

我的问题是,使用“选择”列中的子查询是否可以提高性能?如果是,怎么办?如果否,那么为什么这个主要社区正在使用这种方式? 我也发现他们没有使用外键,为什么?

1 个答案:

答案 0 :(得分:1)

当外部查询正在处理大量行时,相关子查询可能会成为性能问题;因为子查询会针对每一行执行。

此查询看起来最多返回一行,因为user_id是唯一的键。由于外部查询最多返回单行,因此子查询将仅执行一次。

看起来user_group_iduser_group表中的唯一键,因此子查询最多返回一行。 (在更一般的情况下,如果子查询返回的行多于该行,我们将得到一个错误。使用LEFT JOIN,我们将获得多行返回。)


问:使用“选择”列中的子查询是否可以提高性能?

A:任何一种形式都不会影响性能。带有相关子查询的表单可能更快,但差异并不明显。

问:如果可以,怎么办?如果没有,那么为什么这个主要社区正在使用这种方式?

A:这是有效的SQL,可以正常工作,没有动力进行更改。

问:我也发现他们没有使用外键,为什么?

A:不需要RDBMS强制执行参照完整性;如果应用程序正在处理它,那么我们可以避免数据库的开销。

某些存储引擎(例如MyISAM)不强制执行外键约束。

外键有时会干扰管理操作,例如清空和重新加载表。


所有的设计决定;有多种方法可以给猫皮。 (我们只是在这里略读一遍;更深入地潜水将更多地基于观点,从而为哪种方法使猫皮更好是一个论点。)