zoukankan      html  css  js  c++  java
  • [20210413]CBC latch再讨论2.txt

    [20210413]CBC latch再讨论2.txt

    --//这是与别人的再次讨论,实际上验证我以前判断,一般在读读模式下,oracle从11.2.0.4开始全表扫描,唯一索引,rowid模式下,
    --//快速全索引扫描基本不会出现cbc latch,如果出现也许不巧遇到读取cbc latch链时其它sql语句修改或者某种操作读取其链表上其
    --//它数据块.

    --//仅仅全索引扫描以及非索引唯一扫描会出现cbc latch等待事件。
    --//另外我顺便测试_db_hot_block_tracking=true跟踪

    1.环境:
    SCOTT@book> @ ver1
    PORT_STRING                    VERSION        BANNER
    ------------------------------ -------------- --------------------------------------------------------------------------------
    x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

    SYS@book> @ hide  _db_hot_block_tracking
    NAME                   DESCRIPTION                                DEFAULT_VALUE SESSION_VALUE SYSTEM_VALUE ISSES ISSYS_MOD
    ---------------------- ------------------------------------------ ------------- ------------- ------------ ----- ---------
    _db_hot_block_tracking track hot blocks for hash latch contention TRUE          FALSE         FALSE        TRUE  IMMEDIATE

    SYS@book> alter system set "_db_hot_block_tracking"=true scope=memory;
    System altered.

    SYS@book> alter system set "_db_hot_block_tracking"=true scope=both;
    System altered.

    SYS@book> select * from x$kslhot;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1          0          0
    0000000086199AB0          1          1          0          0
    0000000086199AC0          2          1          0          0
    0000000086199AD0          3          1          0          0
    0000000086199AE0          4          1          0          0
    0000000086199AF0          5          1          0          0
    0000000086199B00          6          1          0          0
    0000000086199B10          7          1          0          0
    0000000086199B20          8          1          0          0
    0000000086199B30          9          1          0          0
    10 rows selected.
    --//视乎仅仅记录10个块地址。

    2.建立测试环境:
    SCOTT@book> create table job_times (sid number, time_ela number,method varchar2(20));
    Table created.

    SCOTT@book> create table t as select rownum id ,cast('test' as varchar2(10)) name from dual ;
    Table created.

    SCOTT@book> alter table t modify ( id  not null );
    Table altered.
    --//分析表略。

    SCOTT@book> select rowid from t;
    ROWID
    ------------------
    AAAWdqAAEAAAALbAAA

    SCOTT@book> @ rowid AAAWdqAAEAAAALbAAA
        OBJECT       FILE      BLOCK        ROW ROWID_DBA            DBA                  TEXT
    ---------- ---------- ---------- ---------- -------------------- -------------------- ----------------------------------------
         92010          4        731          0  0x10002DB           4,731                alter system dump datafile 4 block 731 ;

    create index i_t_id on t(id);
    --//create unique index i_t_id on t(id);

    $ cat m10.txt
    set verify off
    host sleep $(echo &&3/50 | bc -l )
    variable vmethod varchar2(20);
    exec :vmethod := '&&2';
    insert into job_times values ( sys_context ('userenv', 'sid') ,dbms_utility.get_time ,:vmethod) ;
    commit ;
    declare
    v_id number;
    v_d date;
    begin
        for i in 1 .. &&1 loop
            select /*+ full(t) &&3 */ count (name) into v_id from t ;
            --select /*+ index(t) &&3 */ count (name) into v_id from t ;
            --select /*+ ROWID(t) &&3 */ count (name) into v_id from t where rowid='AAAWdqAAEAAAALbAAA';
            --select /*+ index(t) &&3 */ count (name) into v_id from t where id=1;
            --select /*+ index_ffs(t) &&3 */ count (*) into v_id from t ;
            --select /*+ index_ffs(t) &&3 */ count (name) into v_id from t ;
            --select /*+ ROWID(t) &&3 */ count (name) into v_id from t where rowid between 'AAAWdqAAEAAAALbAAA' and 'AAAWdqAAEAAAALbAAB';
        end loop;
    end ;
    /
    update job_times set time_ela = dbms_utility.get_time - time_ela where sid=sys_context ('userenv', 'sid') and method=:vmethod;
    commit;
    quit


    --//注:唯一索引,与非唯一索引分开测试。在提示中加入 &&3,主要避免出现cursor: pin S等待事件。
    --//测试时分别注解上面的部分。
    --//另外index_ffs我使用的是select /*+ index_ffs(t) &&3 */ count (*) into v_id from t ;

    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1full=150 {} >/dev/null
    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1index_fs=150 {} >/dev/null
    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1rowid=150 {} >/dev/null
    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1not_uniindex=150 {} >/dev/null
    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1uniindex=150 {} >/dev/null
    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1indexffs=150 {} >/dev/null
    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1indexffs_name=150 {} >/dev/null
    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1rowidbetween=150 {} >/dev/null

    --//注每次测试完成我都重启数据库。这样视图x$kslhot内容会清空。

    3.测试方法在前面的测试已经说明,仅仅记录测试结果:
    --//每次测试前我都单独执行要测试sql语句5次。
    --//使用提示 /*+ full(t) &&3 */
    SYS@book> select * from x$kslhot where KSLHOT_REF>0;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1   16781635          2
    0000000086199AB0          1          1   16781636          1
    --//16781635 = set dba 4,4419 = alter system dump datafile 4 block 4419 = 0x1001143
    --//16781636 = set dba 4,4420 = alter system dump datafile 4 block 4420 = 0x1001144
    SYS@book> @ find_obj 4 4419
       FILE_ID   BLOCK_ID     BLOCKS SEGMENT_TYPE         OWNER  SEGMENT_NAME    PARTITION_NAME   EXTENT_ID      BYTES TABLESPACE_NAME                RELATIVE_FNO     SEGTSN     SEGRFN     SEGBID
    ---------- ---------- ---------- -------------------- ------ --------------- --------------- ---------- ---------- ------------------------------ ------------ ---------- ---------- ----------
             4       4416          8 TABLE                SCOTT  JOB_TIMES                                0      65536 USERS                                     4          4          4       4418
    --//仅仅插入或者修改JOB_TIMES表是出现少量cbc latch。

    --//使用提示 /*+ index(t) &&3 */,注执行计划使用的是全索引扫描。
    SYS@book> select * from x$kslhot where KSLHOT_REF>0;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1   16781643     464011
    --//16781643 = set dba 4,4427 = alter system dump datafile 4 block 4427 = 0x100114b

    SYS@book> @ find_obj 4 4427
       FILE_ID   BLOCK_ID     BLOCKS SEGMENT_TYPE         OWNER  SEGMENT_NAME    PARTITION_NAME   EXTENT_ID      BYTES TABLESPACE_NAME                RELATIVE_FNO     SEGTSN     SEGRFN     SEGBID
    ---------- ---------- ---------- -------------------- ------ --------------- --------------- ---------- ---------- ------------------------------ ------------ ---------- ---------- ----------
             4       4424          8 INDEX                SCOTT  I_T_ID                                   0      65536 USERS                                     4          4          4       4426

    SYS@book> select HEADER_FILE,HEADER_BLOCK from dba_segments where owner='SCOTT' and segment_name='I_T_ID';
    HEADER_FILE HEADER_BLOCK
    ----------- ------------
              4         4426
    --//可以发现cbc latch主要发生在索引段上,当前索引很少也就是root节点上。

    --//使用提示 /*+ ROWID &&3 */
    SYS@book> select * from x$kslhot where KSLHOT_REF>0;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1   16781639          3
    0000000086199AB0          1          1   16781637          9
    0000000086199AC0          2          1   16781635         14
    0000000086199AD0          3          1   16781636         14
    0000000086199AE0          4          1   16781638          2
    --//仅仅插入或者修改JOB_TIMES表是出现少量cbc latch。

    --//使用提示 /*+ index(t) &&3 */
    SYS@book> select * from x$kslhot where KSLHOT_REF>0;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1    4195268          3
    0000000086199AB0          1          1   16781643     386673

    --//16781643 = set dba 4,4427 = alter system dump datafile 4 block 4427 = 0x100114b
    SYS@book> @ find_obj 4 4427
       FILE_ID   BLOCK_ID     BLOCKS SEGMENT_TYPE         OWNER  SEGMENT_NAME    PARTITION_NAME   EXTENT_ID      BYTES TABLESPACE_NAME                RELATIVE_FNO     SEGTSN     SEGRFN     SEGBID
    ---------- ---------- ---------- -------------------- ------ --------------- --------------- ---------- ---------- ------------------------------ ------------ ---------- ---------- ----------
             4       4424          8 INDEX                SCOTT  I_T_ID                                   0      65536 USERS                                     4          4          4       4426
    --//可以发现cbc latch主要发生在索引段上,当前索引很少也就是root节点上。

    --//使用提示 /*+ index(t) &&3 */,但是索引建立为唯一索引看看。
    SCOTT@book> create unique index i_t_id on t(id);
    Index created.

    SYS@book> select * from x$kslhot where KSLHOT_REF>0;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1   16781635          5
    0000000086199AB0          1          1   16781636          4
    0000000086199AC0          2          1   16781637          3
    0000000086199AD0          3          1   16781638          1
    --//仅仅插入或者修改JOB_TIMES表是出现少量cbc latch。

    --//使用提示 /*+ index_ffs(t) &&3 */.
    SYS@book> select * from x$kslhot where KSLHOT_REF>0;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1   16781636          2
    0000000086199AB0          1          1   16781635          1
    0000000086199AC0          2          1   16781637          1
    0000000086199AD0          3          1   16781638          2
    --//仅仅插入或者修改JOB_TIMES表是出现少量cbc latch。

    --//使用提示 /*+ index_ffs(t) &&3 */,建立新索引。查询变为select /*+ index_ffs(t) &&3 */ count (name) into v_id from t ;
    SCOTT@book> create index i_t_id_name on t(id,name);
    Index created.

    SYS@book> select * from x$kslhot where KSLHOT_REF>0;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1   16781635          3
    0000000086199AB0          1          1   16781636          2
    --//仅仅插入或者修改JOB_TIMES表是出现少量cbc latch。

    SCOTT@book> Select method,count(*),round(avg(TIME_ELA),0),sum(TIME_ELA) from scott.job_times group by method order by 3 ;
    METHOD                 COUNT(*) ROUND(AVG(TIME_ELA),0) SUM(TIME_ELA)
    -------------------- ---------- ---------------------- -------------
    p1rowid=150                 150                   2280        341990
    p1uniindex=150              150                   2382        357225
    p1indexffs_name=150         150                   2669        400324
    p1indexffs=150              150                   2698        404737
    p1full=150                  150                   2769        415285
    p1index_fs=150              150                   6748       1012159
    p1not_uniindex=150          150                   7046       1056924
    7 rows selected.

    4.总结:
    --//从执行时间上可以看出在读读模式下,只有全索引扫描以及非索引唯一扫描会出现cbc latch等待事件。而且出现的位置主要在
    --//索引段上,而对应的数据块段没有。
    --//可以看出11.2.0.4以后读读模式,看到cbc latch更多的应该是索引段,而且执行计划可能是索引范围扫描,非唯一索引,全扫描扫
    --//描.
    --//另外快速全索引扫描相当于把索引当作表,也没有出现出现cbc latch。
    --//查询x$kslhot看到涉及JOB_TIMES表应该不算。

    --//补充测试rowid between的情况,注意该数据块一定要先缓存,不然可能走直接路径读。

    $ seq 150 | xargs -I{} -P 150 sqlplus -s -l scott/book @m10.txt 1e5 p1rowidbetween=150 {} >/dev/null

    SYS@book> select * from x$kslhot where KSLHOT_REF>0;
    ADDR                   INDX    INST_ID  KSLHOT_ID KSLHOT_REF
    ---------------- ---------- ---------- ---------- ----------
    0000000086199AA0          0          1    4195268          1
    0000000086199AB0          1          1   16781637          2

    SCOTT@book> Select method,count(*),round(avg(TIME_ELA),0),sum(TIME_ELA) from scott.job_times group by method order by 3 ;
    METHOD                 COUNT(*) ROUND(AVG(TIME_ELA),0) SUM(TIME_ELA)
    -------------------- ---------- ---------------------- -------------
    p1rowid=150                 150                   2280        341990
    p1uniindex=150              150                   2382        357225
    p1indexffs_name=150         150                   2669        400324
    p1indexffs=150              150                   2698        404737
    p1full=150                  150                   2769        415285
    p1rowidbetween=150          150                   4357        653557
    p1index_fs=150              150                   6748       1012159
    p1not_uniindex=150          150                   7046       1056924
    8 rows selected.
    --//rowid between 访问2次数据块,这样对比前面的rowid时间多了差不多1倍。

  • 相关阅读:
    <input type='date'>传到后台怎么接收
    @Conditionnal注解和拦截器
    docker安装nginx
    vue npm run build报错 npm ERR! missing script: build
    阳哥讲面试题(七)Redis五种基本类型,分布式锁
    阳哥讲面试题(六)AOP,循环依赖
    mysql建表报错(this is incompatible with sql_mode=only_full_group_by)
    阳哥讲面试题(五)各种锁,LockSupport,AQS
    SSM_CRUD新手练习(2)配置文件
    Mysql逻辑分层、存储引擎
  • 原文地址:https://www.cnblogs.com/lfree/p/14672943.html
Copyright © 2011-2022 走看看