外连接转换为内连接的情况

一般的情况下外连接如下a right join b on a.id=b.id 那么b一定要作为驱动表,原因在于只有b作为驱动表才能得到完整的结果集,如果a作为驱动,那么返回的结果集
可能不完整,但是在特殊的情况的,可能将外连接转换为内连接
考虑如下的情况


  id  name
  1   g1
  1   g2
  2   g3
  2   g4

a
  id name
  2  gname2

使用如下语句:
select b.id,a.id from 
a right join b on a.id=b.id 
where a.id=2;

先不考虑where a.id=1;
做外连接返回的值应该为
b.id a.id
1     null
1     null
2     2
2     2

现在来考虑a.id =2 ;
那么如果这样过滤那么结果集合如下:

b.id a.id
2     2
2     2

这正是内连接的得到的结果集,也就是说只要a.id 限定为一定固定的非空的值,内连接出来的结构集就能
完全的满足谓词条件过滤后得到结果的全部中间结果集,那么数据库将会进行转换。MYSQL ORACLE都是如此

mysql:
mysql> explain select b.id,a.id from  a right join b on a.id=b.id  where a.id =2;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                              |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
|  1 | SIMPLE      | a     | ALL  | NULL          | NULL | NULL    | NULL |    2 | Using where                                        |
|  1 | SIMPLE      | b     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
2 rows in set (0.00 sec)
a作为了驱动表
oracle:

SQL> select b.id from a right join b on a.id=b.id  where a.id=2;

Execution Plan
----------------------------------------------------------
Plan hash value: 652036164
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |    26 |     5  (20)| 00:00:01 |
|*  1 |  HASH JOIN         |      |     1 |    26 |     5  (20)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL| A    |     1 |    13 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| B    |     2 |    26 |     2   (0)| 00:00:01 |


可以看到本该出现的 HASH JOIN OUTER 没有出现。

但是如果将条件where a.id=2;改为where a.id is null;那么显然这种转换不合理,因为
内连接出来的结果集已经不能满足 a.id is null;的要求。

为什么要这样转换,我们知道在做连接的时候不管是NEST LOOP和HASN JOIN都应该把小表
作为驱动表,效率一般更高,那么外连接限定死了顺序可能大表做为驱动表,那么效率
显然更低,如果做了内连接的转换那么选择的顺序就更多,效率可能得到提高,当然
这和统计数据的精准度有很大的关系。


本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
今天总算抽了些时间把半自动化的脚本完成了大半,目前还缺少两部分的脚本,一部分是安装前的检查脚本,可以做一个预检查。虽然目前来看还不是必须,但是这些是标准和规范的地方,这些条件不满足,失败的概率会加大。另外一部分是安装后的补充脚本,其实安装后还有很多需要注意的地方。 大体想了下,补充的脚本包含下面的部分。 配置crontab,目前的常用job是定期删除归档,定期检查监听的情况 配置iptables ,把主库的防火墙信息拷贝过来,或者作为静态备份,需要是启用 配置大页,这个可以在优化的基础上进行计算,在内核参数

MongoBD 日常操作小节 - 2016-08-09 17:08:09

一、开启Mongodb 密码验证功能 默认安装完mongodb是不用密码验证的,直接输入mongo就可以登入数据库进行相关操作,设置参数auth=true启动mongodb密码验证功能,开启改功能步骤如下: ①、 修改参数文件auth=false,并重启mongodb ②、登入数据库,创建管理员用户(默认是没有管理员账户的) [ root@mon godb ~]  # mongo user admin   db.createUser(     {       user: "admin",       pw

在Buffer Cache中自动大表缓存 - 2016-08-09 17:08:09

约翰,在A银行做DBA。凯特琳,新的首席技术官,她正在为数据库性能问题由于长的I/O响应时间而沮丧。为了提高性能,她希望增加数据库实例的缓冲区缓存,以便在缓存中缓存更多的数据,从而减少了频繁需要去读磁盘。戴比,系统开发工程师,经历了很多这样的问题在她的职业生涯中,她解释说,“我们的应用有很多全表扫描,数据库的全表扫描使用的是直接路径读取(DPR)在表中的数据块,不做缓冲区高速缓存。”因此,添加物理内存到服务器后,增加缓冲区缓存,是不会帮助,因为缓冲区没有用。应用程序可以通过加hits跳过DPRs,使用缓冲

MySQL案例-mysqld got signal 11 - 2016-08-09 14:08:35

-------------------------------------------------------------------------------------------------正文--------------------------------------------------------------------------------------------------------------- 背景: MySQL-5.7.12, debian 8核16G虚拟机 , 业务方反馈在某一
今天的技术问答是刘晨兄的一个问题,提问来自于我新书中的一个实验,刘晨兄非常认真,对我书中的很多细节都进行了测试。 看到这个错误,如果出现end-of-file这类的错误信息,基本可以断定数据库实例是宕了。 找到刘晨兄提到的页码标示,原来和我书中的测试结果有一些差别。 我书中的结果类似这样的形式: 错误代码也完全不同,这个问题该怎么解释呢,这个应该是一个很细节的问题。 首先网络上关于这个错误有很多种说法,很多我不认同。 我们先来复现一下问题,找了一套11.2.0.3的环境测试了一下。 先初始化数据 然后复现问
【故障处理】分布式事务 ORA-01591 错误解决 1    BLOG 文档结构图       2    前言部分 2.1    导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~ : ①  分布式事务的简单概念         ②  ORA-01591 错误解决   Tips: ① 本文在 ITpub ( http://blog.itpub.net/26736162 )、博客园 ( http://www.cnblogs.com/lh
我们有几个项目使用了Windows Server 2008+ ROSE HA+Oracle 的组合方案,但是最近遇到了一个不大不小的麻烦。 甲方在进行故障测试时,断掉了一个网络交换机 的电源 (共有两个网络交换机,对应两个冗余的业务网络),Oracle服务竟然停止了,导致所有的客户端数据库连接中断。 首先,这个测试结果甲方是无法接受的; 其次,这个结果也出乎我们的意料,在另外一个交换机正常工作的情况下,ROSE HA 停止了 Oracle服务。 那么,如何给甲方一个交代呢?在和 ROSE售后经过多次沟通后,
故障现象: 用服务器上面的(客户端)sql server management  stutio 去连接本服务器上的sql server 数据库,如下图:点击连接不报任何错,就是连接不上,一直处于等待状态; 但是通过windows 身份验证是可以连接的,并且是可以正常操作的,如下图:服务器名字不在是个IP,要选择local. 通过这个现象可判断出 数据库本身的服务(通过任务管理器中也可以看出来)是没有问题,只是连接方面出现问题:网络,端口或者是监听之类的问题。 这是网上查到的一篇文档:经验证我的这里是 没有
《 Oracle DBA 工作笔记》第二章 常用工具和问题分析   一.1    BLOG 文档结构图     一.2    本文简介 建荣的新书《 Oracle DBA 工作笔记》第二章的目录如下图,主要讲解了 SQL*Plus 、 exp/imp 、 expdp/impdp 以及常见的问题分析,第二章的目录如下:     下边小麦苗将自己阅读完第二章后整理的一些内容分享给大家。 一.3    第一章内容修改 一.3.1    删除数据库的几种方式 这个内容是第一章( http://blog.itpub
工作中可能需要某一天各个时间段的ash报告或awr报告,手动一个一个生成太费力了.利用 dbms_workload_repository 包再配合sqlplus的spool 可以使这件事情简单一些. 以下示例: 一.批量生成一天的ash报告 1.生成查询语句 #此处是按照15分钟的间隔时间,生成前一天所有的ash报告  的查询语句 select 'spool ash_'||db_unique_name||'_'||inst_id||'_'||to_char(trunc(sysdate-1)+level/9