mysql对子查询的优化改写

mysql对子查询的优化改写《高性能mysql第三版》提到mysql会将in子查询改写成exists查询(书中基于的mysql版本是5.1.50和5.5) 但是在5.6之后,已经优化成使用半连接查询 首先要提的当然是臭名昭著的…

《高性能mysql第三版》提到mysql会将in子查询改写成exists查询(书中基于的mysql版本是5.1.50和5.5)

但是在5.6之后,已经优化成使用半连接查询

首先要提的当然是臭名昭著的MySQL子查询问题,在MySQL5.5及之前的版本,所有有经验的MySQL DBA都会告诉你:绝不能在SQL的WHERE子句中使用子查询,因为那将可能产生灾难性的后果,因为很有可能每扫描一条数据,Where子查询都会被重新执行一遍,workaround的办法就是把WHERE里的子查询提升到FROM中,做成join操作;

和普通join查询不同的是,在semi join中,inner table 的结果集没有重复数据,当两表关联时,例如t1 semi join t2, 当t2存在匹配的记录时,返回t1的记录(t2的记录不会加入操作的结果集中),并且t1的记录最多只返回一次;不像inner join,每一个匹配的记录都会返回,对于semi join,在乎的只是是否匹配子查询而已。

 

 

 

SELECT class_num, class_name FROM class WHERE class_num IN (SELECT class_num FROM roster);

在这里,优化器可以识别出该 IN子句要求子查询仅返回roster表中每个类编号的一个实例 。在这种情况下,查询可以使用半联接;也就是说,该操作仅返回的每一行的一个实例,该实例 class与的行匹配 roster

外部查询规范中允许使用外部联接和内部联接语法,并且表引用可以是基表,派生表或视图引用。

 

 

 

结论:

1、mysql5.5以前会将 in 子查询改写成 exists 查询,如果外部表数据量大的情况下性能会非常糟糕。

2、mysql5.7(5.6没有测过,感兴趣的同学可以测测)对 in 子查询进行了优化,会将sql改写成 join 连接,这样优化器就可以始终优先访问数据量小的表格,减少IO,性能和直接写连接查询几乎是一样的(这点和网上书上说的是有出入的)。

3、exists查询会被分解成一个外部查询和相关子查询(DEPENDENT SUBQUERY),这样子查询会依赖于外部查询的结果,所以始终会对外部表进行全表扫描,外部表数据量大的时候要尤其注意。

 

 

参考文章

http://www.ishenping.com/ArtInfo/3900373.html        mysql数据库中 IN 和 EXISTS 的误区

https://dev.mysql.com/doc/refman/5.5/en/subquery-optimization.html        mysql官方文档解释

https://dev.mysql.com/doc/refman/5.6/en/subquery-optimization.html        mysql官方文档解释

https://yq.aliyun.com/articles/41095     MySQL 5.6的优化器改进

 

注意:

1:可以通过show warnings查看

2:阅读参考文章

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/10550.html

(0)
上一篇 2022-12-25
下一篇 2022-12-25

相关推荐

  • 截取中间字符串的函数_sprintf函数的用法

    截取中间字符串的函数_sprintf函数的用法Excel中的函数非常多,但能记住并且真正能运用到实际工作中的人很少。很多小伙伴都问我怎样才能快速记住函数,答案只有一个:多练。不过学习总是有方法的,下面归类了8组文本函数,这样子可以助你快速掌握Excel文本函数的使用,记得转发收藏起来哦~一、文本中提取字符函数——Left函数、Right函数、Mid函数。LEFT函数:用于对单元格的内容进行截取。从左边第一个字符开始截取,截取指定的长度。RIG…

    2023-03-01
    90
  • DB审核查询平台Archery-「建议收藏」

    DB审核查询平台Archery-「建议收藏」Archery介绍 Archery是archer的分支项目,定位于SQL审核查询平台,旨在提升DBA的工作效率,支持多数据库的SQL上线和查询,同时支持丰富的MySQL运维功能,所有功能都兼容手机端操

    2023-05-08
    100
  • “mysql”_MySQL入门

    “mysql”_MySQL入门MYSQL(基本篇)——一篇文章带你走进MYSQL的奇妙世界 MYSQL算是我们程序员必不可少的一份求职工具了 无论在什么岗位,我们都可以看到应聘要求上所书写的”精通MYSQL等数据库及优化“ 那么我

    2023-05-29
    94
  • SQL Server中CLR表值函数(table-valued function)不能使用WITH(NOLOCK)[亲测有效]

    SQL Server中CLR表值函数(table-valued function)不能使用WITH(NOLOCK)[亲测有效]在SQL Server中,普通的表值函数(table-valued function)是可以使用表提示(Hints-Table)的,那么CLR类型的表值函数(table-valued function

    2023-03-09
    117
  • mysql中key 、primary key 、unique key 与index区别【转】

    mysql中key 、primary key 、unique key 与index区别【转】一、key与primary key区别 解析: KEY wh_logrecord_user_name (user_name) 本表的 字段与 表`user_name`字段建立外键 括号外是建立外键的对

    2023-02-16
    109
  • 挽救数据库性能的 30 条黄金法则[通俗易懂]

    挽救数据库性能的 30 条黄金法则[通俗易懂]1.优化查询,应尽量避免全表扫描,应该在用于检索数据和排序数据的字段上建立索引,如where子句用于搜索,order by子句用于排序,所以在这两个子句涉及到的字段上需要建立索引。 2. 应该尽量避…

    2023-03-11
    92
  • 【原创】CentOS 7 安装解压版mysql5.7「建议收藏」

    【原创】CentOS 7 安装解压版mysql5.7「建议收藏」1、将mysql压缩包解压至 /usr/local 文件夹下,将其改名为mysql#解压tar -zxf mysql-5.7.27-el7-x86_64.tar.gz -C /usr/local/#重

    2022-12-17
    87
  • 使用Python的Sleepy Tie库来构建HTTP客户端

    使用Python的Sleepy Tie库来构建HTTP客户端Sleepy Tie是一个基于Python 3编写的轻量级异步HTTP客户端库。它基于Python标准库中的asyncio和aiohttp模块,提供了简单易用的HTTP请求接口,支持异步和同步请求,以及SSL/TLS加密、HTTP代理等功能。Sleepy Tie库封装了aiohttp库的接口,使得使用者不需要了解HTTP协议的细节,就能快速构建高性能、高并发的HTTP客户端应用。

    2024-03-29
    32

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注