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


    [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.

  • 相关阅读:
    《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九:导航结构层次
    windows live messenger 2009登录失败,提示“错误代码:81000605”的一个解决办法
    《Microsoft SQL Server 2008 MDX Step by Step》学习笔记七:执行聚合(上)
    Java反编译插件Jdclipse导致Eclipse 3.7.2启动崩溃的解决方法
    关于婚姻,你能事先回答这些问题吗?(来自网络)
    邀月的一些其他随笔索引
    《Microsoft SQL Server 2008 MDX Step by Step》学习笔记十一:计算成员和动态命名集
    一点一滴培养你的领袖气质,要经常自我激励(转自网络)
    Firefox中卸载Java Console
    Jquery.Validate验证CheckBoxList,RadioButtonList,DropDownList是否选中
  • 原文地址:https://www.cnblogs.com/lfree/p/9307677.html
Copyright © 2020-2023  润新知