近期,在使用Oracle的过程中,由以下两段代码的执行引发的思考,到底 select * from a,b where a.id = b.idselect * from a inner join b on a.id = b.id 有没有区别?

----- 代码1 ----
select a.xxx, b.xxx, c.xxx
from BUSI_SQJS a,BUSI_SLSH b,BUSI_XSSC c,BUSI_SCJD d,BUSI_ZJQF e,BUSI_ZJBFSD f
where substr(a.HANDLERDAVARTE,1,10) between '2018-01-01' and '2018-11-14'
and a.PROCESS_NUM=b.PROCESS_NUM
and a.PROCESS_NUM=c.PROCESS_NUM
and a.PROCESS_NUM=d.PROCESS_NUM
and a.PROCESS_NUM=e.PROCESS_NUM
and a.PROCESS_NUM=f.PROCESS_NUM; ---- 代码2 ----
select /*+parallel(a,10)*/ a.SQRLX,a.SQRMC,a.SQRSFZMWJ,a.CARDID,a.SQRLXDH,
a.SQRLXDZ,a.SDFS,a.SQJSYJ,a.HAS_SPCL,a.HAS_CLBZ,
e.ZJBH,f.SDFS,a.SQJSJG,b.SQSLJG,c.SQCLXSSCJG,
d.SCJDSCJG
from BUSI_SQJS a
left join BUSI_SLSH b on a.PROCESS_NUM=b.PROCESS_NUM
left join BUSI_XSSC c on a.PROCESS_NUM=c.PROCESS_NUM
left join BUSI_SCJD d on a.PROCESS_NUM=d.PROCESS_NUM
left join BUSI_ZJQF e on a.PROCESS_NUM=e.PROCESS_NUM
left join BUSI_ZJBFSD f on a.PROCESS_NUM=f.PROCESS_NUM
where a.HANDLERDAVARTE >= to_date('2018-01-01','yyyymmdd')
and a.HANDLERDAVARTE <= to_date('2018-11-14','yyyymmdd');

  经过好一番查资料验证,最后更加迷惑。。。

  ……

  ……

  有一说法:inner join优于where多表查询

  另一说法:where a,b 默认就是内连接 inner join

  join 方式的 on 指向连接条件,而其后的 where 条件是筛选连接条件产生的结果集,即先按连接条件连接两表,后根据条件进行筛选。

  inner join 与一般笛卡尔积的区别:inner join是笛卡尔积的特殊形式。如果有表a和表b,表a有m条记录,表b有n条记录,则一般笛卡尔积后得到的记录条数是m*n条,记录之间的组合是随意的。而内连接则是建立在表a和表b的结构中有相同的列名的基础上进行的。

  单纯的select * from a,b是笛卡尔乘积。

  但是,如果对两个表进行关联:select * from a,b where a.id = b.id 就变了,此时就等价于:select * from a inner join b on a.id = b.id,即内连接。

  ……

  ……

  最后,不得已,还是得亲自动手实验。。。

select * from temp_cwh_1128 --
select * from mobile.tb_mr_prod_obj@recom --
---- 1.建立测试表 ----
create table temp_cwh_1128 as
select * from table_xxx a
where a.target_id=''
---- 2.inner join 测试 ---- 4s
select b.prod_code, count(distinct a.account_id)
from temp_cwh_1128 a
inner join mobile.tb_mr_prod_obj@recom b
on a.prod_id = b.prod_id
group by b.prod_code
order by b.prod_code;
---- 3.多表连接测试 ---- 4s
select b.prod_code, count(distinct a.account_id)
from temp_cwh_1128 a, mobile.tb_mr_prod_obj@recom b
where a.prod_id = b.prod_id
group by b.prod_code
order by b.prod_code;

  查看解释计划,两种测试方式的执行过程应该是一致的。

  结论来了!!!

  1.等值连接,不加where条件的时候会产生笛卡尔积,尤其是多表进行连接的时候,产生的笛卡尔积不可预料;但是加上条件a.id = b.id之后,与内连接inner join的效率是一样的,所以“代码1”中的方式理论上来说并没有什么问题;

  2.内连接本质上也是将多表关联之后,筛选满足条件的行;

  3.where a,b的写法不符合规范,最好写成inner join的写法。


END 2018-11-29 16:44:49

Oracle学习笔记:a inner join b与from a,b where a.x=b.x的差异的更多相关文章

  1. Oracle学习笔记之四,SQL语言入门

    1. SQL语言概述 1.1 SQL语言特点 集合性,SQL可以的高层的数据结构上进行工作,工作时不是单条地处理记录,而对数据进行成组的处理. 统一性,操作任务主要包括:查询数据:插入.修改和删除数据 ...

  2. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  3. oracle学习笔记第一天

    oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字   1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...

  4. Oracle学习笔记——点滴汇总

    Oracle学习笔记——点滴汇总 http://www.botangdb.com/ Oracle GI = Grid Infrastructure = ASM + Cluster

  5. Oracle学习笔记之四sp1,Oracle 11g的常用函数

    从Oracle学习笔记之四,SQL语言入门中摘出来的,独立成一章节 3.1 字符类函数 ASCII(c)和CHR(i)    分别用于返回一个字符的ASCII码和返回给定ASCII值所对应的字符. C ...

  6. Oracle学习笔记—数据字典和常用命令(转载)

    转载自: oracle常用数据字典和SQL语句总结 Oracle常用命令大全(很有用,做笔记) 一.Oracle数据字典 数据字典是Oracle存放有关数据库信息的地方,其用途是用来描述数据的.比如一 ...

  7. 并发编程学习笔记(12)----Fork/Join框架

    1. Fork/Join 的概念 Fork指的是将系统进程分成多个执行分支(线程),Join即是等待,当fork()方法创建了多个线程之后,需要等待这些分支执行完毕之后,才能得到最终的结果,因此joi ...

  8. 吴裕雄--天生自然 oracle学习笔记:oracle理论学习详解及各种简单操作例子

    1. 数据库的发展过程 层次模型 -->网状模型 -->关系模型 -->对象关系模型 2. 关于数据库的概念 DB:数据库(存储信息的仓库) DBMS:数据库管理系统(用于管理数据库 ...

  9. oracle学习笔记(一)用户管理

    --oracle学习第一天 --连接 @后面连接数据库实例,具体连接到那个数据库 conn scott/tiger@MYORA1; --修改密码 passw; --显示用户 show user; -- ...

随机推荐

  1. blog 社会化评论插件 多说for china, disqus for global range

    1.disqus https://disqus.com/ https://publishers.disqus.com/engage https://disqus.com/admin/create/ h ...

  2. Java_按位与&,按位或,取反,左移,右移运算符

    //按位与运算& System.out.println(0&0);//0 System.out.println(0&1);//0 System.out.println(1&am ...

  3. IDEA中新建Module时Module name、Content root、Module file location的含义

    如下图测试: 最开始默认情况下,Content root.Module file location两行,最末尾的数据跟Module name是相同的. 现在对三行数据,强制进行不同的命名,Finish ...

  4. THUWC2019爆零记

    Day -1 现在在机房里,准备敲敲板子什么的. 今天晚上放假诶,要好好睡一下.好好睡是不可能的,这辈子不可能的. Day 0 现在在酒店,\(lwh\)神仙在超越,我打了个\(treap\)的板子就 ...

  5. BZOJ 2879 [Noi2012]美食节 | 费用流 动态开点

    这道题就是"修车"的数据加强版--但是数据范围扩大了好多,应对方法是"动态开点". 首先先把"所有厨师做的倒数第一道菜"和所有菜连边,然后跑 ...

  6. 标记,上传并下载自己创建的镜像 image

    1. 首先使用 docker images 查看已有镜像: 2. 获得 docker-whale 的 IMAGE ID,然后为 docker-whale 镜像 image 打上标签 Tag.使用命令: ...

  7. 71. Simplify Path(M)

    71. Simplify Path Given an absolute path for a file (Unix-style), simplify it. For example, path = & ...

  8. Docker:搭建私有仓库(Registry 2.4)

    一.背景 首先,Docker Hub是一个很好的用于管理公共镜像的地方,我们可以在上面找到想要的镜像(Docker Hub的下载量已经达到数亿次):而且我们也可以把自己的镜像推送上去.但是,有的时候, ...

  9. 菜单栏--Dom选择器

    制作一个左侧菜单栏,包含菜单目录和内容 点击菜单栏才会展示内容,否则隐藏内容 二.事例 2.1 菜单栏基本样式 <body> <div style="height: 48p ...

  10. Tomcat权威指南-读书摘要系列9

    从源代码组建Tomcat 安装Apache Ant ant是make的开放源代码的替代品,而且是专门为java程序语言设计. Ant的最初用途是作为Tomcat的组建工具: 之后,Ant成为Java软 ...