干货 | 如何在子查询和联接之间选择
在 联接与子查询:哪个更快?文章我们了解到连接往往比子查询执行得更快。话虽如此,这并不是一条通用准则,因此你可能不希望自动假设联接更可取。正如那篇文章中提到的,如果你需要在查询添加许多联接,数据库服务器就必须做更多的工作,这可能会导致数据检索时间变慢。本文将介绍几个你可以执行的快速测试,比较使用联接的查询和包含子查询的查询,让你可以选择最佳性能的查询。
我们通过 Navicat 简单高效地比较出了结果,欢迎点击 这里 下载 14 天免费全功能试用版。
两个查询,相同结果
大多数时候,你可以使用连接或子查询来编写查询。为了说明这一点,以下有一个从 MySQL Sakila 示例数据库中选择地区及其相关城市和地址的查询。第一个 SELECT 语句使用联接,而第二个 SELECT 语句使用子查询获取完全相同的数据:
SELECT co.Country, COUNT(DISTINCT ci.city_id) AS city_cnt, COUNT(a.city_id) AS address_cnt FROM country co INNER JOIN city ci ON co.country_id = ci.country_id INNER JOIN address a ON ci.city_id = a.city_id GROUP BY co.country_id; SELECT Co.Country, (Select COUNT(1) FROM City Ci WHERE Ci.country_id=co.country_id) AS city_cnt, (Select COUNT(1) FROM Address A INNER JOIN city c on a.city_id=c.city_id WHERE C.country_id=co.country_id) AS address_cnt From Country Co;
在 Navicat 中,我们可以很容易地比较查询结果,因为它可以同时运行多个查询。每个结果集都显示在 SQL 编辑器下的一个选项卡中。在下图中,结果 2 选项卡的内容显示在结果 1 旁边以便快速比较:
查询执行时间
验证了这两个语句是等效的之后,我们现在可以比较它们的执行时间。
为此,我们可以选择其中一个语句,然后点击“运行”按钮。只要在编辑器中选择了文本,该按钮的标签就会変为“运行已选择的”。在画面底部可以看到运行时间是 0.020秒:
对第二条语句执行相同操作,得出运行时间为 0.021秒 。时间差异很小,但会随着数据量的增加而增长:
比较执行计划
一个查询的执行计划可以揭示很多关于它执行速度的信息。在 Navicat 中,我们可以点击“解释”按钮来查看执行计划。 虽然需要一些练习才能熟练地解译解释的结果,但这样做可以在尝试确定查询的效率时带来好处。
解释 1 选项卡显示第一个(联接)查询的执行计划。我们可以一眼看出它涉及 3 个 SIMPLE 选择:
同時,解释 2 选项卡列出了一个 PRIMARY 选择,然后是三个 DEPENDENT SUBQUERY。即使不深入探究,我们也可以看到执行第二个(子查询)语句需要一个额外的步骤:
总结
虽然本文似乎证实了联接与子查询:哪个更快?文章得出的结论,但比较连接和子查询方法颇有价值的。在任何情况下,子查询仍然有优于联接的时候,例如当你必须即时计算聚合值并在外部查询中使用它进行比较时。
往期回顾
1. 盗版引发设备瘫痪 | 官方严正声明:切勿在非官方渠道购买或下载 Navicat 软件
2. Navicat 荣获 Microsoft 金牌合作伙伴
3. Navicat 16.3 正式支持 OceanBase 企业版
5. Navicat 发展史
相关文章
- linux下如何查询未知库所依赖的包
- Android实例-如何使用系统剪切板(XE8+小米2)
- ACCESS-如何多数据库查询(跨库查询)
- 携程SQL上线流程优化,如何从源头扼杀慢查询?
- C#.NET常见问题(FAQ)-Combobox如何设置不可以编辑
- 生活娱乐 工商银行如何查询开户行
- Windows如何使用bin文件下的命令
- 什么事跨域以及如何解决跨域(转)
- 如何查找MySQL中查询慢的SQL语句
- 如何通过ps -ef|grep tomcat只获得你需要的查询进程,排除掉grep本身的进程信息
- MariaDB Galera Cluster 部署(如何快速部署MariaDB集群)
- 如何在java List中进行模糊查询
- MySQL优化:如何避免回表查询?_什么是索引覆盖?
- 表格存储新手指南:如何实现分页查询
- 如何正确实现Page接口分页,用PageImpl 自定义分页
- Linux 0.11-操作系统如何获取时间-17
- 如何自行查询SAP Spartacus Organization Unit List的取数逻辑
- 如何通过Restful API的方式读取SAP Commerce Cloud的Product图片
- 如何在backoffice里创建Hybris image container以及分配给product
- 如何给VirtualBox虚拟机的ubuntu LVM分区扩容
- SQLite软件的下载安装,如何创建/添加/更新/查询/删除数据
- mysql根据分组和条件查询以后如何统计记录的条数
- 14 乘法器:如何像搭乐高一样搭电路(下)?
- 【备份】如何在 PADS Layout 中选择 Gerber 274X 格式
- GEOquery只下载临床信息如何只查看geo的临床信息而不下载矩阵
- 技术 or 管理?程序员如何做好职业规划?