[20180713]关于hash join 测试中一个疑问.txt

--//上个星期做的测试,链接: http://blog.itpub.net/267265/viewspace-2157424/
--//前几天在家里12c上重复测试,才发现自己没注意细节问题.

1.环境:
SCOTT@test01p> @ ver1
PORT_STRING                    VERSION        BANNER                                                                               CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0           12.1.0.1.0     Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production              0

create table t1 as select level id   ,'t1'||to_char(level) name from dual connect by level<=4;
create table t2 as select level+1 id ,'t2'||to_char(level) name from dual connect by level<=4;
insert into t1 values (null,'t1null');
insert into t2 values (null,'t2null');
commit ;
--//分析略.
insert into t2  select rownum+4 ,'t2'||to_char(rownum+4) from dual connect by level<=10000;
commit;

SCOTT@test01p> select rowid,t2.* from t2 where id<=4 or id is null;
ROWID                      ID NAME
------------------ ---------- --------------------
AAAaT5AAJAAAADLAAA          2 t21
AAAaT5AAJAAAADLAAB          3 t22
AAAaT5AAJAAAADLAAC          4 t23
AAAaT5AAJAAAADOAAA            t2null

--//我自己一直以为执行insert into t2 values (null,'t2null');应该插入的数据块与id=2的数据块一样,实际情况不同.

SCOTT@test01p> @ rowid AAAaT5AAJAAAADLAAA
    OBJECT       FILE      BLOCK        ROW ROWID_DBA            DBA                  TEXT
---------- ---------- ---------- ---------- -------------------- -------------------- ----------------------------------------
    107769          9        203          0  0x24000CB           9,203                alter system dump datafile 9 block 203 ;

SCOTT@test01p> @ rowid AAAaT5AAJAAAADOAAA

OBJECT       FILE      BLOCK        ROW ROWID_DBA            DBA                  TEXT
---------- ---------- ---------- ---------- -------------------- -------------------- ----------------------------------------
    107769          9        206          0  0x24000CE           9,206                alter system dump datafile 9 block 206 ;

--//实际上ctas插入的第一块紧接着表段HEADER_BLOCK.
SCOTT@test01p> select SEGMENT_NAME,SEGMENT_TYPE,HEADER_FILE,HEADER_BLOCK from dba_segments where owner=user and segment_name='T2';
SEGMENT_NAME         SEGMENT_TYPE         HEADER_FILE HEADER_BLOCK
-------------------- -------------------- ----------- ------------
T2                   TABLE                          9          202

2.这样就很好解析我前面遇到的情况:
SCOTT@test01p> alter session set statistics_level=all;
Session altered.

SCOTT@test01p> select * from t1 where id not in (select id from t2 ) and id is not null;
no rows selected

SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  86bz316n141w9, child number 0
-------------------------------------
select * from t1 where id not in (select id from t2 ) and id is not null
Plan hash value: 1275484728
------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |       |    14 (100)|          |      0 |00:00:00.01 |      14 |       |       |          |
|*  1 |  HASH JOIN ANTI NA |      |      1 |      1 |    12 |    14   (0)| 00:00:01 |      0 |00:00:00.01 |      14 |  1888K|  1888K| 1090K (0)|
|*  2 |   TABLE ACCESS FULL| T1   |      1 |      4 |    32 |     4   (0)| 00:00:01 |      4 |00:00:00.01 |       7 |       |       |          |
|   3 |   TABLE ACCESS FULL| T2   |      1 |  10005 | 40020 |    10   (0)| 00:00:01 |    956 |00:00:00.01 |       7 |       |       |          |
------------------------------------------------------------------------------------------------------------------------------------------------

--//表T2做全表扫描buffers=7.而实际全表扫描逻辑读31.而且实际读T2记录数是956.
SCOTT@test01p> select count(*) from t2 ;
  COUNT(*)
----------
     10005

SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  34jwra7jk76u5, child number 0
-------------------------------------
select count(*) from t2
Plan hash value: 3321871023
-------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |    10 (100)|          |      1 |00:00:00.01 |      31 |
|   1 |  SORT AGGREGATE    |      |      1 |      1 |            |          |      1 |00:00:00.01 |      31 |
|   2 |   TABLE ACCESS FULL| T2   |      1 |  10005 |    10   (0)| 00:00:01 |  10005 |00:00:00.01 |      31 |
-------------------------------------------------------------------------------------------------------------

SCOTT@test01p> select count(*) from t2 where DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid) between 203 and 205;
  COUNT(*)
----------
       955
--//这样扫描dba=9,203到9,205的记录数是955,加上dba=9.206第1条记录是id is NULL,因为存在Null 记录,查询就停止扫描T2.
--//而如果交换表连接顺序:
SCOTT@test01p> select /*+ SWAP_JOIN_INPUTS(@"SEL$5DA710D3" "T2"@"SEL$2") */ * from t1 where id not in (select id from t2 ) ;
no rows selected

SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  aqy7dusnfb5gm, child number 0
-------------------------------------
select /*+ SWAP_JOIN_INPUTS(@"SEL$5DA710D3" "T2"@"SEL$2") */ * from t1
where id not in (select id from t2 )
Plan hash value: 2739594415
-----------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |      |      1 |        |       |    14 (100)|          |      0 |00:00:00.01 |       7 |       |       |          |
|*  1 |  HASH JOIN RIGHT ANTI NA|      |      1 |      2 |    24 |    14   (0)| 00:00:01 |      0 |00:00:00.01 |       7 |  1753K|  1753K| 1482K (0)|
|   2 |   TABLE ACCESS FULL     | T2   |      1 |  10005 | 40020 |    10   (0)| 00:00:01 |    956 |00:00:00.01 |       7 |       |       |          |
|   3 |   TABLE ACCESS FULL     | T1   |      0 |      5 |    40 |     4   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |       |       |          |
-----------------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$5DA710D3
   2 - SEL$5DA710D3 / T2@SEL$2
   3 - SEL$5DA710D3 / T1@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("ID"="ID")
--//这样T2表扫描到id is null时就停止.而T1表根本不做全表扫描操作.starts=0.

[20180713]关于hash join 测试中一个疑问.txt的更多相关文章

  1. [20180904]工作中一个错误.txt

    [20180904]工作中一个错误.txt --//昨天看我提交一份修改建议,发现自己写的sql语句存在错误.--//链接:http://blog.itpub.net/267265/viewspace ...

  2. mysql 8.0.18 hash join测试(内外网首文)

    CREATE TABLE COLUMNS_hj as select * from information_schema.`COLUMNS`; INSERT INTO COLUMNS_hj SELECT ...

  3. [20180705]关于hash join 2.txt

    [20180705]关于hash join 2.txt --//昨天优化sql语句,执行计划hash join right sna,加入一个约束设置XX字段not null,逻辑读从上万下降到50.- ...

  4. 8.深入TiDB:解析Hash Join实现原理

    本文基于 TiDB release-5.1进行分析,需要用到 Go 1.16以后的版本 我的博客地址:https://www.luozhiyun.com/archives/631 所谓 Hash Jo ...

  5. 数据库 Hash Join的定义,原理,算法,成本,模式和位图

    Hash Join只能用于相等连接,且只能在CBO优化器模式下.相对于nested loop join,hash join更适合处理大型结果集       Hash Join的执行计划第1个是hash ...

  6. 浅谈SQL Server中的三种物理连接操作(HASH JOIN MERGE JOIN NESTED LOOP)

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

  7. ClsoSee(v2) Alpha测试中!这是一个临时的帮助页面...

    Clso See 测试中,最新的更新信息会显示在这里,欢迎您随时关注新版本动态. 您可以单击这里让程序打开本地帮助文件(新说明.txt) 等程序完成后,会制作专门的帮助页面. 因为采用了键盘Hook技 ...

  8. 浅谈SQL Server中的三种物理连接操作(Nested Loop Join、Merge Join、Hash Join)

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

  9. Bullet:关于ORACLE中的HASH JOIN的参数变化

    Oracle在7.3引入了hash join. 但是在Oracle 10g及其以后的Oracle数据库版本中,优化器,实际是CBO,也是因为HASH JOIN仅适用于CBO,在解析目标SQL时是否考虑 ...

随机推荐

  1. [宏]__stringify

    Linux内核中有如下两个宏: #define __stringify_1(x...) #x #define __stringify(x...) __stringify_1(x) 写代码测试如下: # ...

  2. java开发,年薪15W的你和年薪50W的他的差距

      在这个IT系统动辄就是上亿流量的时代,Java作为大数据时代应用最广泛的语言,诞生了一批又一批的新技术,包括HBase.Hadoop.MQ.Netty.SpringCloud等等 .   一些独角 ...

  3. IO流查找文件然后写入TXT文档

    今天领导让分析日志,把日志中所有登录过的员工信息都拿出来.于是.把日志摘下来谢了这段代码 import java.io.BufferedReader;import java.io.BufferedWr ...

  4. Django--自定义 Command 命令

    Django 对于命令的添加有一套规范,你可以为每个app 指定命令.通俗一点讲,比如在使用manage.py文件执行命令的时候,可以自定制自己的命令,来实现命令的扩充. commands的创建 1. ...

  5. Java读取Properties的几种方法

    本文转载自:http://blog.csdn.net/chjttony/article/details/5927613 每次用完每次忘相对与绝对...

  6. koa执行过程原理分析

    本文原创,转载请注明出处https://i.cnblogs.com/EditPosts.aspx?postid=5710639 我们大家都知道,当koa接到请求经过中间件时,当执行到 yield ne ...

  7. Android中Enum(枚举)的使用

    简介 enum 的全称为 enumeration, 是 JDK 1.5  中引入的新特性,存放在 java.lang 包中. 创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.l ...

  8. 从零开始学 Web 之 HTML5(二)表单,多媒体新增内容,新增获取操作元素,自定义属性

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  9. Docker修改默认网段

    因阿里云服务器VPC默认占用了172.16.0.0/16 网段,与Docker里的网段相同,导致Docker里无法连接VPC服务器.后来找到的解决方案是修改Docker的默认网段. 由于Docker默 ...

  10. SQL 必知必会·笔记<20>高级SQL特性

    1. 约束 约束(constraint)就是管理如何插入或处理数据库数据的规则.DBMS通过在数据库表上施加约束来实施引用完整性. 1.1 主键 主键是一种特殊的约束,用来保证一列(或一组列)中的值是 ...