mysql - 为什么 OpenCart 使用子查询而不是 LEFT JOIN?
问题描述
最近我正在研究我发现使用子查询而不是 LEFT JOIN 的 opencart 源代码。
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 . "'";
我的问题是,在 Select 列中使用子查询是否有任何性能改进?如果是的话怎么办?如果不是,那么为什么这个主要社区使用这种方式?我还发现他们没有使用外键,知道为什么吗?
解决方案
当外部查询处理大量行时,相关子查询可能会成为性能问题;因为子查询会为每一行执行。
看起来这个查询最多返回一行,因为它看起来像是user_id
一个唯一键。由于外部查询(最多)返回一行,子查询将只执行一次。
它也看起来像是表user_group_id
中的唯一键user_group
,因此子查询将最多返回一行。(在更一般的情况下,如果子查询返回多于一行,我们会得到一个错误。使用 LEFT JOIN,我们会返回多行。)
问:在 Select 列中使用子查询是否有任何性能提升?
答:任何一种形式都不会造成性能损失。具有相关子查询的表单可能会更快,但差异并不显着。
问:如果是的话怎么办?如果不是,那么为什么这个主要社区使用这种方式?
A:它是有效的 SQL,它可以工作,并且没有任何改变的动力。
问:我还发现他们没有使用外键,知道为什么吗?
答:没有要求 RDBMS 强制执行参照完整性;如果应用程序正在处理它,那么我们可以避免数据库中的开销。
一些存储引擎(例如 MyISAM)不强制执行外键约束。
外键有时会干扰管理操作,例如清空和重新加载表。
这都是设计决策;有多种方法可以给猫剥皮。(我们只是在这里略过表面;更深入地潜水将更多地基于意见,以争论哪种方式给猫剥皮更好。)
推荐阅读
- android - 是否可以将两个不同的应用程序上传到具有高度相似代码库的 Apple Store 和 Play Store?
- redirect - Laravel 重定向到带有参数的命名路由返回状态 200
- bash - 每天保留一个文件,一个 3 天和 1 周,并删除其他文件
- angular - 没有为作者字段触发角度表单验证
- c# - 如何从 OkObjectResult 获取动态属性
- github - 如何使用 Pygithub API 执行“拉”命令
- c# - 为什么这个 XPath 表达式适用于一个节点而不适用于另一个节点?
- angularjs - 如何使 $scope.$broadcast 在 Ipad 中工作?
- asp.net-core - 作为 Windows 服务部署的 .net core(2.2) Web 应用程序的访问日志路径是什么
- amazon-web-services - AWS EC2 外部 IP 在重启时不断变化,导致 DNS 问题