2019独角兽企业重金招聘Python工程师标准>>>

这是个老生常谈的问题,平时在简单使用过程中,都能得到想要的结果,但是对于各自的性能,以及适用场景,我们该注意什么?假如现在有表a(主表),b,进行关联查询出a表字段。(mysql版本为5.7)
join:
表连接,这里我只说inner join连接。如果不涉及到order by,首先可以考虑使用join,其次,考虑a,b表对应关系,如果是多对一,或者是一对一,那么,就没有其它顾虑了,在这种场景下,join的性能比exists,in要好。如果a,b是一对多关系,而且查询包括未建立索引的字段,那查出来的结果就会有重复,如果这时你想去重而加了distinct,那该sql的执行计划就会出现using temporary,性能将大打折扣(如果只查询出a.id,或者其它索引字段,那distinct效率还是挺高的)。如果这种一对多的情况确实想用join怎么办?那只能程序中去重了。

那如果需要order by a表字段,使用join会怎样?首先解释一下个概念:驱动表。什么是驱动表?mysql在join表连接时会选择一个结果集较小的表作为驱动表,再以此遍历被驱动表,explain查看执行计划时,第一行的表就是驱动表。如果对驱动表的字段order by,是没有问题的。但是如果对被驱动表order by,则会产生using temporary,以及filesort,性能可想而知!你能保证a表一定是驱动表吗?不一定!就算没有其它任何查询条件,全表数据a表比b表小,但是随着时间推移,a表的数据也可能变得比b表大,另外再加上查询条件,两个表实际返回的结果集不敢确定谁大谁小。所以在有order by的情况下,建议使用exists或者in子查询代替,但是需要注意的是,关于in,如果a表数据量级比b表小,性能可能不是很高,而且,有时候mysql优化器会将in转化为join表连接,执行计划其实是一样的。而对于exists,如果a表数据量级比b表大,性能很可能不高,至于原因,看下面的分析。

exists:
很强大的谓词,关联子查询,子查询不返回任何结果集,只返回true或者false。在mysql5.6以前的版本中,mysql默认会将in独立子查询转化为exists关联子查询(你去看一看老版本下这两者的执行计划,是一样的)。假如a表有m行数据,b表有n行数据,它会用a表的m行数据一行一行的和b表里的数据做比较,复杂度为:m+m*n,所以它的瓶颈在于a表的数据量级,如果a表数据量级比b表大,那逻辑IO的次数就多,性能越糟糕。所以exists适合a表数据量级比b表小的子查询。

in:
最常用的子查询,在mysql5.7版本中,有些in子查询会被优化为join表连接。in适合什么场景呢?在另一篇文章《MySQL中in(常量列表)的执行计划》中提到过,如果in后面的value list很少,而且字段上存在索引,甚至是主键,那性能还是相当高的。不过即使存在索引,当value list达到一个临界值(无法确定这个经验值,根据整个表的量级而决定)时,会导致ALL全表扫描。所以,和exists使用场景相反,in适合a表数据量级比b表大的子查询。

转载于:https://my.oschina.net/u/3263645/blog/2872144

mysql中使用join exists in时该注意的问题相关推荐

  1. MySQL中In与Exists的区别

    MySQL中In与Exists的区别 1 例子 2 EXISTS和IN的介绍 2.1 exists 2.2 in 2.3 使用上的区别 3 EXISTS和IN的性能分析 4 总结 1 例子 有两个表需 ...

  2. MySQL中Left Join用法

    MySQL中Left Join用法  例子:  user表:  id name  ---------  1 libk  2 zyfon  3 daodao  user_action表:  user_i ...

  3. mysql的join语句使用_在MySQL中使用JOIN语句进行连接操作的详细教程

    到目前,我们已经学习了从一个表中获取数据.这是简单的需要,但在大多数现实MySQL的使用,经常需要将数据从多个表中的一个单一的查询. 可以使用多个表中的单一SQL查询.在MySQL中联接(join)行 ...

  4. 软件测试mysql面试题:mysql中 in 和 exists 区别?

    mysql中 in 和 exists 区别? mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都认为exist ...

  5. MySQL中IN和EXISTS的用法

    exists对外表用loop逐条查询,每次查询都会查看exists的条件语句,当 exists里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返回当前loop到的这条记录, ...

  6. MySQL中关于JOIN的用法全解

    一.一张图看懂 MySQL 的各种 JOIN 用法 二.准备表和数据,测试 1.创建两个表测试 CREATE TABLE `forlan_class`(`id` bigint(20) NOT NULL ...

  7. mysql 变量被引号括住_【已解决】mysql中操作表的字段名时是否一定要用反引号括起来...

    折腾: 期间,看到别人: 实现Pyspider爬虫结果的自定义ResultWorker – 简书    @staticmethod def escape(string): return '`%s`' ...

  8. 自己对mysql中的Join的理解

    注: 本文是我自己的学习思路.自己的理解还很浅,而且很有可能是错的.文章只是辅助自己理解.若有看官阅读了,请指出我的错误,但请不要侮辱我. cityjoin表: +----+-----------+- ...

  9. MySQL中left join、right join与inner join的区别

    1.数据库 1.1.作者表 1.2.图书表 1.3.出版社表 2.left join left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录. 2.1.sql语句 selec ...

最新文章

  1. hung-yi lee_p13_反向传播
  2. SQL基本语法和书写格式
  3. SAP MM 初阶之不常用事务代码MEBV
  4. linux(centos) 常用命令
  5. 移动端重构系列5——等分,居中等
  6. 爱思助手安卓能用吗_手机资讯:【爱思助手6.0】音乐铃声导入教程
  7. ubuntu的codelite中代码运行后出现/usr/bin/codelite_exec: 22: /usr/bin/codelite_exec
  8. Attention和增强RNN (Attention and Augmented Recurrent Neural Networks)
  9. 多角度让你彻底明白yield语法糖的用法和原理及在C#函数式编程中的作用
  10. java jpeg压缩解码_JPEG图像压缩原理简介
  11. 在chrome开发者工具中观察函数调用栈、作用域链、闭包
  12. Hack_All_The_Things——探索IoT相关的攻击研究和渗透测试
  13. 用74ls90组成二十四进制计数器_六十进制应该怎么怎么设计呢?
  14. 可调稳压电源lm317实验报告_可调直流稳压电源实验报告 -
  15. Docker 中jmap报错:Can‘t attach to the process: ptrace(PTRACE_ATTACH问题
  16. 运动的“点”与“线”,竟然能产生错觉???
  17. excel拆分数据如何按行拆分
  18. iSCSI存储技术全攻略【存储部落】云存储|云计算|云服务
  19. 元胞自动机 C实现 + OpenCV界面
  20. Ubuntu的安装以及重新安装的注意点(保存以前的用户数据)

热门文章

  1. 物理学家发现粒子是如何自我组装的
  2. 哈工大等实现人工肌肉重大突破登上 Science!多国科学家联合实现全新驱动机理...
  3. 3D器官和骨骼将使移植清单成为历史
  4. 不只是华为/阿里/百度/小米/京东,AIoT已然成为资本与新兴企业都认可的赚钱方向...
  5. 一场科技盛宴,一次“盈”满天下 安创成长营五期Demo Day完美收官
  6. 干货|全球人工智能专利分布战情图
  7. 年薪超 1400 万美元!苹果 CEO 库克去年薪酬大曝光!
  8. 是我,一行代码三个 Bug!!! | 每日趣闻
  9. 陈芳,高考之后我要学计算机专业,将来做 IT 发财了,我就娶你!
  10. 我的zsh配置, 2019最新方案