• row migeration and row chain


    row migeration:当发出update导致记录行长增加,block的剩余空间不足以存放这条记录,就会产生行迁移,发生行迁移时rowid不会改变,原来的block中会用一个指针存放这条记录在新的block中的地址,发生行迁移会对性能产生影响,因为读这条记录会读两个BLOCK。

    row chain:当一个BLOCK不足以存放下一条记录的时候,就会发生行连接,这个时候oracle会把这条记录分成几个部分,分别存放在几个block中,然后把这几个block chain起来。行连接同样会影响性能,因为读一条记录至少会读两个BLOCK.

    下面来模拟row migeration ,row chain ,然后解决掉这两个问题。

    row migeration

    SQL> create table test1(x number,y varchar2(100)) pctfree 0;

    Table created.
    SQL> create table test2(x number,y varchar2(100)) pctfree 20;

    Table created.
    SQL> begin
      2  for i in 1..3000 loop
      3  insert into test1 values(i,'robinson');
      4  insert into test2 values(i,'luobingsen');
      5  end loop;
      6  commit;
      7  end;
      8  /

    PL/SQL procedure successfully completed.
    SQL> analyze table test1 compute statistics;

    Table analyzed.

    SQL> c/test1/test2
      1* analyze table test2 compute statistics
    SQL> /

    Table analyzed.

    SQL> select chain_cnt from dba_tables where table_name='TEST1';

     CHAIN_CNT
    ----------
             0  

    SQL> c/TEST1/TEST2
      1* select chain_cnt from dba_tables where table_name='TEST2'
    SQL> /

     CHAIN_CNT
    ----------
             0
    SQL> update test1 set y='robinsonluobingsen';

    3000 rows updated.

    SQL> c/test1/test2;
      1* update test2 set y='robinsonluobingsen'
    SQL> /

    3000 rows updated.

    SQL> commit;

    Commit complete.
    SQL> analyze table test1 compute statistics;

    Table analyzed.

    SQL> c/test1/test2;
      1* analyze table test2 compute statistics
    SQL> /

    Table analyzed.
    SQL> select chain_cnt from dba_tables where table_name='TEST1';

     CHAIN_CNT
    ----------
          1771  test1表有1771行发生了行迁移(注意,chain_cnt记录的是行迁移和行连接的数量,不要以为这个值大于0就发生了行迁移,也可能是行连接,此时要分析表的结构,查看到底是行连接或者是行迁移

    SQL> c/TEST1/TEST2;
      1* select chain_cnt from dba_tables where table_name='TEST2'
    SQL> /

     CHAIN_CNT
    ----------
           510  test2表有510行发生了行迁移
    可以 alter table move 命令消除行迁移,以及降低HWM,不过这个时候这个应用不能访问该表,而且该表上的index会无效,因为move之后的ROWID变了,此时需要重新创建索引(rebulid)。

    SQL> alter table test1 move;

    Table altered.

    SQL> analyze table test1 compute statistics;

    Table analyzed.

    SQL> select chain_cnt from dba_tables where table_name='TEST1';

     CHAIN_CNT
    ----------
             0   行迁移消除了
    SQL> alter table test2 move;

    Table altered.

    SQL> analyze table test2 compute statistics;

    Table analyzed.

    SQL> select chain_cnt from dba_tables where table_name='TEST2';

     CHAIN_CNT
    ----------
             0  行迁移和消除了
    row chain

    SQL> show parameter db_block_size

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    db_block_size                        integer     8192
    SQL> create table test3(a char(2000),b char(2000),c char(2000),d char(2000),e char(2000));

    Table created.
    我block size 为8k,也就是说一个block能存下大约8 k 的数据,(实际上小于8k,因为block header,tail 需要占用空间),也就是8192 byte,但是我创建的表的一行要占10000
    byte,所以这个时候一个block 肯定不能存下一条记录。

    SQL> insert into test3 values('robinson','luoluo','oracle','dba','aaaaa');

    1 row created.

    SQL> commit;

    Commit complete.
    SQL> analyze table test3 compute statistics;

    Table analyzed.
    SQL> select chain_cnt from dba_tables where table_name='TEST3';

     CHAIN_CNT
    ----------
             1   可以看到发生了行连接

    要消除行连接,我们需要将block size 改大 ,db_block_size 是不能更改的,但是我们可以在创建tablespace 的时候指定 blocksize ,如果要创建这样的 tablespace ,需要首先指定 db_nk_cache_size ,然后 通过move 命令 将 发生了行连接的表 move 到 blocksize 较大的 tablespace.

    SQL> show parameter db_16k

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    db_16k_cache_size                    big integer 12M
    SQL> create tablespace rowchain blocksize 16384;

    Tablespace created.  注意我使用了OMF,这样不需指定数据文件名和大小,由ORACLE自动管理

    SQL> alter table test3 move tablespace rowchain;

    Table altered.
    SQL> analyze table test3 compute statistics;

    Table analyzed.
    SQL>  select chain_cnt from dba_tables where table_name='TEST3';

     CHAIN_CNT
    ----------
             0  可以看到行连接消除了



  • 相关阅读:
    Linux的常用用法
    docker入门实践01
    airflow安装rest api插件发现airflow webserver服务不能启动的解决办法
    27.Spark中transformation的介绍
    1.Cloudera Manager安装
    win10系统不能ping通vmware虚假机解决办法
    在airflow的BashOperator中执行docker容器中的脚本容易忽略的问题
    AirFlow后台运行调度程序
    Airflow怎么删除系统自带的DAG任务
    airflow删除dag不在页面显示
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330696.html
Copyright © 2020-2023  润新知