在日常优化过程中,发现一个怪事情,同一个SQL出现两个完全不一样执行计划,left join 连驱动表都可以变成不一样。

对于left join,如果where条件里有被关联表过滤,left join有可能被转成inner join ,本案例中shopInfo有ShopCategory = 'LOC'过滤条件; 保证shopInfo的记录非NULL,因此left join在优化过程中可以转为inner join。 那么O和S的JOIN顺序就是可以交换的。

验证结论:

创建表:

--班级表
CREATE TABLE T_CLASS(
class_id int not null,
class_name VARCHAR2(100)
);
添加索引
alter table T_CLASS add index inx_class_id(class_id);
--学生表
CREATE TABLE T_STUDENT(
student_id int not null,
class_id int not null,
student_name VARCHAR(100),
age int,
sex int
)
添加索引
alter table T_STUDENT add index index_age(AGE);
--班级数据
insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (1, '一班'); insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (2, '二班'); insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (3, '三班'); insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (4, '四班'); insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (5, '五班');
--学生数据
insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (1, 1, '李1', 3, '1'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (2, 1, '李2', 2, '1'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (3, 1, '李3', 3, '1'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (4, 2, '李4', 4, '1'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (5, 2, '李5', 3, '2'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (6, 2, '李6', 3, '1'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (7, 3, '李7', 6, '2'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (8, 3, '李8', 4, '2'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (9, 2, '李9', 2, '2'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (10, 2, '李10', 3, '1'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (11, 3, '李11', 3, '2'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (12, 2, '李12', 8, '2'); insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (13, 1, '李13', 6, '2');

案例1:B表有where条件且不为null

案例2: A表和B表均有where条件且不为null

案例3:A表和B表均有where条件且不为null,删除B表索引

结论:

left join 只有被关联表有where条件,且其过滤条件优于关联表的情况下,mysql优化器才转成inner join.

福禄·运维
泽西

mysql left join转inner join的更多相关文章

  1. mysql join 和left join 对于索引的问题

    今天遇到一个left join优化的问题,搞了一下午,中间查了不少资料,对MySQL的查询计划还有查询优化有了更进一步的了解,做一个简单的记录: select c.* from hotel_info_ ...

  2. 【转】mysql的union、left join、 right join、 inner join和视图学习

    1.联合 union 进行多个查询语句时,要求多次查询的结果列数必须一样.此时,查询的结果以第一个sql语句的列名为准且union会自动去重复我们应该使用union all. 例...... 1.联合 ...

  3. MySql学习(三) —— 子查询(where、from、exists) 及 连接查询(left join、right join、inner join、union join)

    注:该MySql系列博客仅为个人学习笔记. 同样的,使用goods表来练习子查询,表结构如下: 所有数据(cat_id与category.cat_id关联): 类别表: mingoods(连接查询时作 ...

  4. MySQL的几种连接 join/inner join/cross join/逗号/left join/right join/natural join

    转载请注明出处!! 之前数据表连接操作多使用逗号或者join,对几种连接的概念一直浑浑噩噩,最近研究了一波,把这些连接的区别搞明白了.   连接:A xjoin B(主表 操作 关联表)  selec ...

  5. mysql inner join,full outer join,left join,right jion

    https://sites.google.com/site/349624yu/courses/mysql/mysqldbgjzcx inner join,full outer join,left jo ...

  6. mysql not in、left join、IS NULL、NOT EXISTS 效率问题记录

    原文:mysql not in.left join.IS NULL.NOT EXISTS 效率问题记录 mysql not in.left join.IS NULL.NOT EXISTS 效率问题记录 ...

  7. MySQL中Left Join和Right Join的理解

    虽然之前一直见过两个Join,对于其具体的含义也在参考书上读过,但是一直没有记住.现在换一种方式进行学习,改为实验方式理解. Left Join 测试表: 表结构很简单,test包括两个int字段,t ...

  8. MySQL中链接查询inner join与left join使用

    连接查询其实就是对两个表记录做笛卡尔乘积.如果不指定连接条件的话,则会对每行都做笛卡尔乘积,这样最后返回的结果树就会是两个表记录数的乘积:如果指定则,则仅对符合列条件的行进行笛卡尔乘积,并返回结果.在 ...

  9. mysql中的几种join 及 full join问题

    [注意]:Oracle数据库支持full join,mysql是不支持full join的,但仍然可以同过左外连接+ union+右外连接实现 初始化SQL语句:   /*join 建表语句*/   ...

  10. MySQL连接查询(inner join,left join和right join的区别)

    关系数据库由多个相关表组成,这些表使用已知为外键列的常用列链接在一起. 因此,从业务角度来看,每个表中的数据是不完整的. 例如,在示例数据库(yiibaidb)中,使用orderNumber列链接的o ...

随机推荐

  1. 北航OO(2020)第二单元博客作业

    第二单元第一次作业 多线程设计策略 第一次作业的想法是设计三个线程:输入线程,调度器线程以及电梯线程.输入线程获取请求并发送给调度器线程:调度器线程通过查询电梯线程的状态(等待.停靠以及移动),并综合 ...

  2. Mybatis-plus在原有的select查询语句中动态追加查询条件

    一.适用场景 1.使用了xml形式的mapper.2.不想在select查询中大量使用<if>标签来判断条件是否存在而加入条件. 二.步骤 1.自定义wrapper继承QueryWrapp ...

  3. Ansible_静态和动态清单文件管理

    一.利用主机模式选择主机 1.应用静态清单主机 1️⃣:主机模式用于指定要作为play或临时命令的目标的主机:在最简单的形式中,清单中受管主机或主机组的名称就是指定该主机或主机组的主机模式 简单演示实 ...

  4. 控制器网关/dns设置

    如果控制器ping内网可以,但是ping不同外网,十有八九是因为网关的问题,可以使用route命令设置网关,如设置为192.168.31.1(不是192.168.31.0),route add def ...

  5. 【错误解决】The prefix "context" for element "context:component-scan" is not bound

    在配置spring相关的applicationContext.xml文件时报以上错误 原因是缺失context的namespace. http://www.springframework.org/sc ...

  6. Linux 系统日志和系统信息常用命令介绍

    日志文件 日 志 文 件 说 明 /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一 /var/log/secure 与安全相关的日志信息 / ...

  7. linux下 find命令使用

     按名称查找  find . -name filename [root@vps repo]# ls README.md vps.sh[root@vps repo]# find . -iname vps ...

  8. CSS定位特性

    CSS属性书写顺序 布局定位属性:display / position / float / clear / visibility / overflow 自身属性:width / height / ma ...

  9. KMP算法中我对获取next数组的理解

    之前在学KMP算法时一直理解不了获取next数组的函数是如何实现的,现在大概知道怎么一回事了,记录一下我对获取next数组的理解. KMP算法实现的原理就不再赘述了,先上KMP代码: 1 void g ...

  10. redux 源码浅析

    redux 源码浅析 redux 版本号: "redux": "4.0.5" redux 作为一个十分常用的状态容器库, 大家都应该见识过, 他很小巧, 只有 ...