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

相关推荐

  • java连接数据库(jdbc)的标准规范「终于解决」

    java连接数据库(jdbc)的标准规范「终于解决」java连接数据库的标准规范 JDBC全称:java database connectivity ,是sun公司提供的Java连接数据库的标准规范。 localhost和127.0.0.1 都是表示当

    2023-04-11
    145
  • Ubuntu卸载Python

    Ubuntu卸载PythonPython语言的应用日益广泛,越来越多的应用开始依赖于Python。但是,有些Ubuntu用户可能需要卸载Python,可能是为了节省磁盘空间或是为了避免Python版本冲突。本文将会介绍如何在Ubuntu上卸载Python,希望能够为读者提供有用的信息。

    2024-05-01
    45
  • PostgreSQL DBA最常用SQL[亲测有效]

    PostgreSQL DBA最常用SQL[亲测有效]背景 建立视图, 方便查询 create schema dba; create view dba.invalid_index as select indisvalid, indexrelid::reg

    2023-06-11
    117
  • MySQL学习(3)-[亲测有效]

    MySQL学习(3)-[亲测有效]ps:此随笔基于mysql 5.7.*版本。 已知root账户密码进行登录 格式:mysql [-h地址] [-p端口] -u用户名 -p密码 省略不写地址或端口则自动使用默认。(地址:localh

    2023-06-02
    115
  • 时序数据库druid_时序数据库网站

    时序数据库druid_时序数据库网站一 了解InfluxDB的必要性 时序数据库主要存放的数据 Time series data is a series of data points each associated with a spe

    2023-04-25
    117
  • lxml安装失败

    lxml安装失败lxml是Python上一个功能强大的XML/HTML处理库。它基于Cython以及libxml2/libxslt库构建,提供了简单易用的接口和快速的解析速度。在许多数据处理、爬虫、数据挖掘等领域,lxml被广泛应用。因而,安装lxml也成为Python学习者不可避免的一部分。

    2024-07-14
    22
  • MySQL之group by分组查询

    MySQL之group by分组查询有如下数据: 一个简单的分组查询的案例 按照部门编号deptno分组,统计每个部门的平均工资。 select deptno,avg(sal) avgs from emp group by deptno

    2023-04-22
    122
  • mysql的索引面试_mysql 索引详解

    mysql的索引面试_mysql 索引详解1、什么是索引? 索引是帮助MySQL高效获取数据的数据结构(有序)。 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现

    2023-05-01
    123

发表回复

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