有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多。

一、优化原则

小表驱动大表,即小的数据集驱动大得数据集。在知道什么是小表驱动达大表之前,我们先来了解两个查询关键字,IN 与 EXISTS。我们通过两段查询语句先来了解一下它们的作用。我建立了两张表,一张员工表,一张部门表,员工表中有部门id 这个属性,将这两张表关联起来。

我们先使用IN 来查询数据:

SELECT *
FROM t_emp
WHERE dept_id IN (SELECT dept_id FROM t_dept)
LIMIT 5;

查询结果:由于有很多的员工信息,在这里我就只查询5 条数据。

+-------------+----------+------------+--------------+---------+
| emp_id      | emp_name | emp_gender | emp_email    | dept_id |
+-------------+----------+------------+--------------+---------+
| 00000000177 | 41d80    | m          | 41d80@zc.com |       1 |
| 00000000178 | a74b8    | m          | a74b8@zc.com |       1 |
| 00000000179 | 661ca    | m          | 661ca@zc.com |       1 |
| 00000000180 | 9413d    | m          | 9413d@zc.com |       1 |
| 00000000181 | 7d577    | m          | 7d577@zc.com |       1 |
+-------------+----------+------------+--------------+---------+

接下里使用EXISTS 来查询数据:

 SELECT * FROM t_emp WHERE EXISTS (SELECT 1 FROM t_dept WHERE t_dept.dept_id = t_emp.dept_id) LIMIT 5;

查询结果:与上面的结果一样。

+-------------+----------+------------+--------------+---------+
| emp_id      | emp_name | emp_gender | emp_email    | dept_id |
+-------------+----------+------------+--------------+---------+
| 00000000177 | 41d80    | m          | 41d80@zc.com |       1 |
| 00000000178 | a74b8    | m          | a74b8@zc.com |       1 |
| 00000000179 | 661ca    | m          | 661ca@zc.com |       1 |
| 00000000180 | 9413d    | m          | 9413d@zc.com |       1 |
| 00000000181 | 7d577    | m          | 7d577@zc.com |       1 |
+-------------+----------+------------+--------------+---------+

既然IN 和 EXISTS 都可以用来查询数据,那它们两个有什么区别呢?

SELECT *
FROM t_emp
WHERE dept_id IN (SELECT dept_id FROM t_dept);// 这条SQL 语句相当于:
for SELECT dept_id FROM t_deptfor SELECT * FROM t_emp WHERE t_emp.dept_id = t_dept.dept_id

这里虽然我们编写的SQL 语句是主查询员工信息,子查询部门id ,但是MySql 的执行顺序会先执行子查询,再执行主查询,然后获得我们要查询的数据。

 SELECT * FROM t_emp WHERE EXISTS (SELECT 1 FROM t_dept WHERE t_dept.dept_id = t_emp.dept_id);// 这条SQL 语句相当于:
for SELECT * FROM t_emp for SELECT * FROM t_dept  WHERE t_dept.dept_id = t_emp.dept_id

我们可以将EXISTS 语法理解为:将主查询的数据放在子查询中做条件验证,根据结果TRUE 和 FALSE 来决定主查询中的数据是否需要保留。EXISTS 子查询只返回TRUE 或 FALSE ,因此子查询中的SELECT * 可以是SELECT 1 或者其他,MySql 的官方说在实际执行时会忽略SELECT 清单,因此是没有 什么区别的。EXISTS 子查询其实在执行时,MySql 已经对它做了一些优化并不是对每条数据进行对比。

二、总结

在实际操作过程中我们要对两张表的dept_id 都设置索引。在一开始我们就讲了一个优化原则即:小表驱动大表,在我们使用IN 进行关联查询时,通过上面IN 操作的执行顺序,我们是先查询部门表再根据部门表查出来的id 信息查询员工信息。我们都知道员工表肯定会有很多的员工信息,但是部门表一般只会有很少的数据信息,我们事先通过查询部门表信息查询员工信息,以小表(t_dept)的查询结果,去驱动大表(t_emp),这种查询方式是效率很高的,也是值得提倡的。

但是我们使用EXISTS 查询时,首先查询员工表,然后根据部门表的查询条件返回的TRUE 或者 FALSE ,再决定员工表中的信息是否需要保留。这不就是用大的数据表(t_emp) 去驱动小的数据表小的数据表(t_dept)了吗?虽然这种方式也可以查出我们想要的数据,但是这种查询方式是不值得提倡的。

当t_emp(外层大表) 表中数据多于 t_dept(子表小表) 表中的数据时,这时我们使用IN 优于 EXISTS。当t_dept(子表小表) 表中数据多于 t_emp(外层大表) 表中的数据时(我们这里只是假设),这时我们使用EXISTS 优于 IN。因此是使用IN 还是使用EXISTS 就需要根据我们的需求决定了。但是如果两张表中的数据量差不多时那么是使用IN 还是使用 EXISTS 差别不大。

MySQL IN、Exist关联查询时,我们为什么建议小表驱动大表?相关推荐

  1. mysql 小表连大表_MySQL 表之间关联查询时,为什么建议小表驱动大表?

    有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多. 一.优化原则 小表驱动大表,即小的数据集驱动大 ...

  2. MySQL关联查询时,我们为什么建议小表驱动大表?

    作者:留兰香丶 blog.csdn.net/codejas/article/details/78632883 有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们 ...

  3. MySql小表驱动大表

    有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多. 一.优化原则 小表驱动大表,即小的数据集驱动大 ...

  4. mysql 大表 驱动_MySql 小表驱动大表

    在了解之前要先了解对应语法 in 与 exist. in后的括号的表达式结果要求之输出一列字段.与之前的搜索字段匹配,匹配到相同则返回对应行. mysql的执行顺序是先执行子查询,然后执行主查询,用子 ...

  5. Mysql优化原则_小表驱动大表IN和EXISTS的合理利用

    //假设一个for循环 for($i = 0; $i < 10000; $i++) { for ($j = 0; $i < 50; $j++){} }for($i = 0; $i < ...

  6. mysql算法优化原则_Mysql优化原则_小表驱动大表IN和EXISTS的合理利用

    //假设一个for循环 for($i = 0; $i < 10000; $i++) { for ($j = 0; $i < 50; $j++) { } } for($i = 0; $i & ...

  7. Mysql之小表驱动大表

    Mysql之小表驱动大表 1 什么是小表驱动大表 2 为什么使用小表驱动大表 3 判断驱动表与非驱动表 4 Exists和in的使用场景 1 什么是小表驱动大表 用小的数据集去驱动(可理解为匹配)大的 ...

  8. MySQL高级知识(十六)——小表驱动大表

    前言:本来小表驱动大表的知识应该在前面就讲解的,但是由于之前并没有学习数据批量插入,因此将其放在这里.在查询的优化中永远小表驱动大表. 1.为什么要小表驱动大表呢 类似循环嵌套 for(int i=5 ...

  9. 【MySQL】小表驱动大表

    1.概述 前言:本来小表驱动大表的知识应该在前面就讲解的,但是由于之前并没有学习数据批量插入,因此将其放在这里.在查询的优化中永远小表驱动大表. 1.为什么要小表驱动大表呢 类似循环嵌套 for(in ...

最新文章

  1. html和css占前端的多少比例,【CSS】前端怎么实现像chrome浏览器的百分比缩放同样的效果?...
  2. python中文件路径格式_Python应用-临床路径格式转换
  3. P1060 开心的金明(01背包)
  4. 【摘录】MTK按键扫描原理及相关代码
  5. 怎么修改腾讯视频的昵称
  6. 【LeetCode】Maximum Product Subarray 求连续子数组使其乘积最大
  7. 机器学习之-BoostedTree
  8. mysql8从入门到精通电子书_MySQL 8从入门到精通(视频教学版)
  9. D - RGB Triplets(前缀和+思维)
  10. 除了LoRa和SigFox,物联网低功耗广域网络还有哪些
  11. 网络技术| 说说计算机网络及IP地址 -- 网络基础 跳线制作 IP地址配置
  12. ICP许可证怎么申请?
  13. 小米路由器的服务器无响应怎么回事,小米路由器常见问题与解决方法(高级功能) | 192路由网...
  14. 周转时间 平均周转时间 带权周转时间 平均带权周转时间
  15. 应用在电视触摸屏中的十四通道智能触摸芯片
  16. (转)高并发高流量网站架构详解
  17. ART Mterp Interpreter 解释 bytecode
  18. 第二章(1) SCADA/EMS系统的概述
  19. 【数学】【裂项相消】Integration-牛客
  20. selenium+phantomjs 模拟抓取淘宝分类信息

热门文章

  1. 南农沈其荣组Science子刊揭示番茄早期微生物组功能决定成年健康
  2. Science:中科院植物所马克平组揭示土壤真菌与树木密度的关系
  3. ggplot2笔记9:绘图需要的数据整理技术
  4. 扩增子分析解读3格式转换,去冗余,聚类
  5. R语言使用caret包的preProcess函数进行数据预处理:对所有的数据列进行center中心化、scale标准化(每个数据列减去平均值、除以标准差)、设置参数为center和scale
  6. python使用numpy包编写自定义函数计算MAPE(平均绝对百分比误差)指标mean absolute percentage error (MAPE)、MAPE指标解读、MAPE指标使用的注意事项
  7. pandas使用sort_values函数对dataframe的日期数据列进行排序(设置ascending参数进行正序或者倒序排序)
  8. R语言使用yardstick包的conf_mat函数计算多分类(Multiclass)模型的混淆矩阵、并使用summary函数基于混淆矩阵输出分类模型评估的其它详细指标(kappa、npv等13个)
  9. R语言ggplot2可视化:ggplot2中使用element_text函数设置轴标签文本粗体字体(bold text,使x轴和Y轴的标签文本都使用粗体字体)、注意是轴标签而非轴标题
  10. R双样本t检验(WELCH TWO-SAMPLE T-TEST)